# Paragraphs

> Format paragraphs with ParagraphFormat in ServerTextControl: alignment, indents, spacing, tab stops and page breaks, ParagraphStyle and numbered lists.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Document Processing > Paragraphs
- **8612 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/paragraphs/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/paragraphs/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/paragraphs/llms-full.txt

---

How text is laid out on a page is decided paragraph by paragraph: its alignment, indents, spacing, page breaks, style, list numbering and writing direction. Your code reads the paragraphs of a document, formats them, defines paragraph styles that keep documents consistent, turns paragraphs into bulleted, numbered and structured lists and sets right-to-left paragraphs for Arabic and Hebrew text.

Character attributes such as fonts and colors are described in [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/llms-full.txt), and [Create a Document](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/document-processing/create/#format-characters-and-paragraphs) shows a first centered paragraph with a frame. Paste an example into *Program.cs* of a console application to run it.

### How Paragraphs Work

A paragraph ends with a carriage return and a line feed (`\r\n`). [ServerTextControl.Paragraphs](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/paragraphs-property/llms-full.txt) contains the paragraphs of the main text; headers, footers and text frames have their own `Paragraphs` collection. Every document has at least one paragraph, and paragraphs are numbered from 1.

A [Paragraph](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/llms-full.txt) has these properties:

| Property | Contains |
|---|---|
| [Number](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/number-property/llms-full.txt) | The number of the paragraph, starting at 1 |
| [Start](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/start-property/llms-full.txt), [Length](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/length-property/llms-full.txt) | The one-based position of its first character and its number of characters, including the paragraph end |
| [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/text-property/llms-full.txt), [Lines](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/lines-property/llms-full.txt) | Its text and its number of lines |
| [Format](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/format-property/llms-full.txt) | Its formatting, as a [ParagraphFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/llms-full.txt) object |
| [FormattingStyle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/formattingstyle-property/llms-full.txt) | The name of its paragraph style |
| [ListFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/listformat-property/llms-full.txt), [ListNumberText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/listnumbertext-property/llms-full.txt) | Its list formatting, and the number of a numbered list item with the text before and after it |

The following program prints the paragraphs of *Documents/sample.docx* with their style, number of lines and alignment, and saves the first paragraph as HTML:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("Documents/sample.docx", StreamType.WordprocessingML);

    Console.WriteLine($"{tx.Paragraphs.Count} paragraphs");

    foreach (Paragraph paragraph in tx.Paragraphs)
    {
        Console.WriteLine($"#{paragraph.Number} \"{paragraph.FormattingStyle}\", " +
            $"{paragraph.Lines} line(s), {paragraph.Format.Alignment}: " +
            $"{paragraph.ListNumberText}{paragraph.Text}");
    }

    // The paragraph at text position 0
    Paragraph first = tx.Paragraphs.GetItem(0);

    if (first != null)
    {
        string html;
        first.Save(out html, StringStreamType.HTMLFormat);
        Console.WriteLine(html);
    }
}
```

`tx.Paragraphs[1]` returns a paragraph by its number. [GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphcollection/getitem-method/llms-full.txt) returns the paragraph at a text position, which starts at 0, or `null`. [Paragraph.Save](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraph/save-method/llms-full.txt) saves the paragraph to a string or a byte array. For selected text, [Selection.ParagraphFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/selection/paragraphformat-property/llms-full.txt) gets and sets the formatting of all selected paragraphs.

### Format Paragraphs

Assign a `ParagraphFormat` object to `Paragraph.Format` to format a paragraph. The following program formats a heading, a body paragraph, a note with a frame and an appendix that starts on a new page:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    tx.Text = "Terms and Conditions\r\n" +
              "These terms apply to all orders placed with our company. Please read them carefully before you place an order.\r\n" +
              "Note: Prices are subject to change without notice.\r\n" +
              "Appendix";

    // Heading: centered, 12 pt space after it, on the same page as the next paragraph
    tx.Paragraphs[1].Format = new ParagraphFormat(HorizontalAlignment.Center)
    {
        BottomDistance = 240, // 240 twips = 12 pt
        KeepWithNext = true
    };

    // Body: justified, indented on both sides, first line indented further, 1.5 line spacing
    tx.Paragraphs[2].Format = new ParagraphFormat()
    {
        Alignment = HorizontalAlignment.Justify,
        LeftIndent = 720,     // 0.5 inch
        RightIndent = 720,
        HangingIndent = -360, // negative: the first line is indented by another 0.25 inch
        LineSpacing = 150,    // percent of the font size
        BottomDistance = 120,
        KeepLinesTogether = true
    };

    // Note: background color and a box frame
    tx.Paragraphs[3].Format = new ParagraphFormat()
    {
        BackColor = System.Drawing.Color.LightYellow,
        Frame = Frame.Box,
        FrameDistance = 60,
        FrameLineWidth = 10
    };

    // Appendix: always starts at the top of a page
    tx.Paragraphs[4].Format = new ParagraphFormat() { PageBreakBefore = true };

    tx.Save("paragraphs.pdf", StreamType.AdobePDF);
}
```

All distances are measured in twips, 1/1440 inch. The properties of `ParagraphFormat`:

| Property | Sets | Default |
|---|---|---|
| [Alignment](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/alignment-property/llms-full.txt) | `Left`, `Right`, `Center` or `Justify` | `Left` |
| [LeftIndent](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/leftindent-property/llms-full.txt), [RightIndent](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/rightindent-property/llms-full.txt) | The indents from the left and right edge of the text area | `0` |
| [HangingIndent](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/hangingindent-property/llms-full.txt) | The hanging indent; a negative value indents the first line further | `0` |
| [TopDistance](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/topdistance-property/llms-full.txt), [BottomDistance](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/bottomdistance-property/llms-full.txt) | The space before and after the paragraph | `0` |
| [LineSpacing](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/linespacing-property/llms-full.txt) | The line spacing in percent of the font size, from 1 to 10000 | `100` |
| [AbsoluteLineSpacing](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/absolutelinespacing-property/llms-full.txt) | A fixed line spacing in twips; 0 takes it from the font | `0` |
| [KeepLinesTogether](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/keeplinestogether-property/llms-full.txt) | No page break inside the paragraph | `false` |
| [KeepWithNext](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/keepwithnext-property/llms-full.txt) | The paragraph stays on the page of the next paragraph | `false` |
| [PageBreakBefore](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/pagebreakbefore-property/llms-full.txt) | The paragraph always starts at the top of a page | `false` |
| [WidowOrphanLines](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/widoworphanlines-property/llms-full.txt) | How many lines of the paragraph must not be separated from the rest at a page break, from 0 (off) to 3 | `0` |
| [Frame](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/frame-property/llms-full.txt), `FrameStyle`, `FrameLineWidth`, `FrameLineColor`, `FrameDistance` | Lines around the paragraph with their style, width, color and distance from the text | No frame, 15 twips |
| [BackColor](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/backcolor-property/llms-full.txt) | The background color | Transparent |
| [Direction](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/direction-property/llms-full.txt) | `LeftToRight` or `RightToLeft` text | `LeftToRight` |

A heading that must start on a new page is better served by `PageBreakBefore` than by a page break character: when the text before it grows or shrinks, a forced page break can leave an empty page, as the blog article [Document Templates Tip: Say No to Forced Page Breaks](https://www.textcontrol.com/blog/2024/05/28/document-templates-tip-say-no-to-forced-page-breaks/) shows.

Tab stops are set with three arrays of `ParagraphFormat`: [TabPositions](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/tabpositions-property/llms-full.txt) with the positions in twips, [TabTypes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/tabtypes-property/llms-full.txt) with the types `LeftTab`, `RightTab`, `CenterTab`, `DecimalTab` or `RightBorderTab` and [TabLeaders](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/tableaders-property/llms-full.txt) with the values `None`, `Period`, `Dot`, `Dash` or `Underline`, which fill the space before a tab stop. A paragraph has up to 14 tab stops.

### Use Paragraph Styles

A [ParagraphStyle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstyle/llms-full.txt) combines character attributes and paragraph formatting under a name. Paragraphs that use a style change when the style changes, which keeps all headings or body paragraphs of a document alike. The following program creates styles for headings and body text, applies them and then changes the color of the headings:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    tx.Text = "Delivery Terms\r\n" +
              "Shipping\r\n" +
              "Goods are shipped within five business days.\r\n" +
              "Payment Terms\r\n" +
              "Invoices are payable within 30 days.";

    // Heading style, based on the root style [Normal]
    ParagraphStyle heading = new ParagraphStyle("Contract Heading");
    heading.FontName = "Arial";
    heading.FontSize = 320; // 16 pt
    heading.Bold = true;
    heading.ParagraphFormat.TopDistance = 240;
    heading.ParagraphFormat.BottomDistance = 120;
    heading.ParagraphFormat.KeepWithNext = true;
    tx.ParagraphStyles.Add(heading);

    // Subheading style, based on the heading style
    ParagraphStyle subheading = new ParagraphStyle("Contract Subheading", "Contract Heading");
    subheading.FontSize = 280; // 14 pt
    tx.ParagraphStyles.Add(subheading);

    // Body text style
    ParagraphStyle body = new ParagraphStyle("Contract Body");
    body.ParagraphFormat.Alignment = HorizontalAlignment.Justify;
    body.ParagraphFormat.LineSpacing = 120;
    tx.ParagraphStyles.Add(body);

    // Apply the styles to the paragraphs
    tx.Paragraphs[1].FormattingStyle = "Contract Heading";
    tx.Paragraphs[2].FormattingStyle = "Contract Subheading";
    tx.Paragraphs[3].FormattingStyle = "Contract Body";
    tx.Paragraphs[4].FormattingStyle = "Contract Heading";
    tx.Paragraphs[5].FormattingStyle = "Contract Body";

    // Change a style later: every paragraph that uses it changes
    ParagraphStyle existing = tx.ParagraphStyles.GetItem("Contract Heading");

    if (existing != null)
    {
        existing.ForeColor = System.Drawing.Color.DarkBlue;
        existing.Apply();
    }

    tx.Save("styles.docx", StreamType.WordprocessingML);
}
```

The code works as follows:

- The [ParagraphStyle constructor](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstyle/constructor/llms-full.txt) with a name creates a style based on the root style `[Normal]`, which uses Arial at 10 pt by default. With the name of a base style as second parameter, the new style inherits the attributes of that style.
- The character attributes, such as `FontName` and `Bold`, and [ParagraphStyle.ParagraphFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstyle/paragraphformat-property/llms-full.txt) define the style.
- [ParagraphStyles.Add](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstylecollection/add-method/llms-full.txt) adds the style to the document, and `Paragraph.FormattingStyle` applies it to a paragraph by its name.
- [GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstylecollection/getitem-method/llms-full.txt) returns a style by its name, or `null`. After changing a style, [Apply](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/formattingstyle/apply-method/llms-full.txt) applies it to the document.

Documents loaded from MS Word bring their styles along, such as "Heading 1", and `Paragraph.FormattingStyle` returns their names. [ParagraphFormat.StructureLevel](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/structurelevel-property/llms-full.txt) gives a style or paragraph a level between 0 and 10, where 0 is body text and the levels 1 to 10 are the ones a table of contents is generated from, as [Tables of Contents](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/tables-of-contents/llms-full.txt) describes. The blog article [Applying and Updating Formatting Styles from Master Templates (DOTX) in DOCX Documents](https://www.textcontrol.com/blog/2024/10/10/applying-and-updating-formatting-styles-from-master-templates-dotx-in-docx-documents/) copies the styles of one document to others.

#### List, Change and Remove Styles

[ServerTextControl.ParagraphStyles](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/paragraphstyles-property/llms-full.txt) is a [ParagraphStyleCollection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstylecollection/llms-full.txt), and [ServerTextControl.InlineStyles](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/inlinestyles-property/llms-full.txt), with the character styles described in [Use Inline Styles](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/#use-inline-styles), an [InlineStyleCollection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/inlinestylecollection/llms-full.txt). Both derive from [FormattingStyleCollection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/formattingstylecollection/llms-full.txt). The following program lists the paragraph styles of a document with their base styles and removes one of them:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("styles.docx", StreamType.WordprocessingML);

    foreach (ParagraphStyle style in tx.ParagraphStyles)
    {
        // null for the root style
        string baseStyle = style.BaseStyle?.Name ?? "(none)";
        Console.WriteLine($"{style.Name}, based on {baseStyle}, followed by {style.FollowingStyle}");
    }

    // The heading paragraphs are followed by body text when a user presses ENTER
    ParagraphStyle heading = tx.ParagraphStyles.GetItem("Contract Heading");

    if (heading != null)
    {
        heading.FollowingStyle = "Contract Body";
    }

    // true if the style was removed
    bool removed = tx.ParagraphStyles.Remove("Contract Subheading");
    Console.WriteLine($"Style removed: {removed}");

    tx.Save("styles-changed.docx", StreamType.WordprocessingML);
}
```

The code works as follows:

- [BaseStyle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/formattingstyle/basestyle-property/llms-full.txt) returns the style a style is based on, a `ParagraphStyle` or an `InlineStyle`, and `null` for the root style. It's read only; the base style is set with the constructor.
- [FollowingStyle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstyle/followingstyle-property/llms-full.txt) is the name of the style the next paragraph gets when a user presses ENTER at the end of a paragraph with this style. It's saved with the document and matters when the document is edited, for example in the Document Editor.
- [Remove](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/formattingstylecollection/remove-method/llms-full.txt) takes the name of a style and returns `true` if the style was removed.

Inline styles have two more methods. [InlineStyle.IsInheritedFromParagraph](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/inlinestyle/isinheritedfromparagraph-method/llms-full.txt) tells whether attributes of the style come from the surrounding paragraph, and [InlineStyle.ResetToParagraph](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/inlinestyle/resettoparagraph-method/llms-full.txt) makes attributes follow the paragraph again. Both take a combination of [InlineStyle.Attributes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/inlinestyle/attributes-enumeration/llms-full.txt) values, such as `InlineStyle.Attributes.FontName | InlineStyle.Attributes.FontSize`. [Selection.RemoveInlineStyles](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/selection/removeinlinestyles-method/llms-full.txt) removes the inline styles from the selected text.

### Create Bulleted and Numbered Lists

A [ListFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/llms-full.txt) turns a paragraph into a list item. The following program creates a bulleted list, a numbered list, a second numbered list that starts again with a) and a structured list whose items show the numbers of their parent levels:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    tx.Text = "Required documents:\r\n" + // paragraph 1
              "Passport\r\n" +
              "Birth certificate\r\n" +
              "Steps:\r\n" +              // paragraph 4
              "Fill in the form\r\n" +
              "Sign the form\r\n" +
              "Later:\r\n" +              // paragraph 7
              "Wait for confirmation\r\n" +
              "Pay the fee\r\n" +
              "Contents:\r\n" +           // paragraph 10
              "Scope\r\n" +
              "Definitions\r\n" +
              "Obligations";

    // Bulleted list
    ListFormat bullets = new ListFormat(ListType.Bulleted);
    tx.Paragraphs[2].ListFormat = bullets;
    tx.Paragraphs[3].ListFormat = bullets;

    // Numbered list: 1. 2.
    ListFormat numbers = new ListFormat(ListType.Numbered) { TextAfterNumber = "." };
    tx.Paragraphs[5].ListFormat = numbers;
    tx.Paragraphs[6].ListFormat = numbers;

    // Numbered lists continue by default: restart the numbering, with letters a) b)
    tx.Paragraphs[8].ListFormat = new ListFormat(ListType.Numbered)
    {
        NumberFormat = NumberFormat.Letters,
        TextAfterNumber = ")",
        RestartNumbering = true
    };
    tx.Paragraphs[9].ListFormat = new ListFormat(ListType.Numbered)
    {
        NumberFormat = NumberFormat.Letters,
        TextAfterNumber = ")"
    };

    // Structured list: the numbers of higher levels are shown in front of lower levels, 1. 1.1. 2.
    tx.Paragraphs[11].ListFormat = new ListFormat(ListType.Structured)
    {
        Level = 1,
        NumberFormat = NumberFormat.ArabicNumbers,
        RestartNumbering = true
    };
    tx.Paragraphs[12].ListFormat = new ListFormat(ListType.Structured) { Level = 2, NumberFormat = NumberFormat.ArabicNumbers };
    tx.Paragraphs[13].ListFormat = new ListFormat(ListType.Structured) { Level = 1, NumberFormat = NumberFormat.ArabicNumbers };

    foreach (Paragraph paragraph in tx.Paragraphs)
    {
        Console.WriteLine($"{paragraph.ListNumberText} {paragraph.Text}");
    }

    tx.Save("lists.docx", StreamType.WordprocessingML);
}
```

Saved as PDF, the document shows the four lists: bullets, the numbers 1. and 2., the letters a) and b) of the restarted list, and the structured list 1., 1.1. and 2., whose second-level item carries the number of its parent in front of its own. The structured list sets `NumberFormat` explicitly: without it, the Core engine continues the letters of the list before it and numbers the items a., a.a. and b.

![The result of the program: a bulleted list, a numbered list with 1. and 2., a restarted list with a) and b) and a structured list numbered 1., 1.1. and 2.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/list-types-output.20d6e17d.webp)

The properties of `ListFormat`:

| Property | Sets | Default |
|---|---|---|
| [Type](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/type-property/llms-full.txt) | `None`, `Bulleted`, `Numbered` or `Structured` | `None` |
| [NumberFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/numberformat-property/llms-full.txt) | `ArabicNumbers` (1, 2, 3), `Letters` (a, b, c), `CapitalLetters`, `RomanNumbers` or `SmallRomanNumbers` | `ArabicNumbers` |
| [FirstNumber](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/firstnumber-property/llms-full.txt), [RestartNumbering](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/restartnumbering-property/llms-full.txt) | The first number, and whether a new numbered list begins | `1`, `false` |
| [Level](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/level-property/llms-full.txt) | The list level, from 1 to 10 | `1` |
| [TextBeforeNumber](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/textbeforenumber-property/llms-full.txt), [TextAfterNumber](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/textafternumber-property/llms-full.txt) | Text before and after the number, up to 20 characters | — |
| [BulletCharacter](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/bulletcharacter-property/llms-full.txt), [FontName](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/fontname-property/llms-full.txt) | The bullet character and its font | — |
| [HangingIndent](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/listformat/hangingindent-property/llms-full.txt) | The distance between the number or bullet and the text, in twips | `360` |

A paragraph style can carry a list format of its own through [ParagraphStyle.ListFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphstyle/listformat-property/llms-full.txt). The blog article [Convert Plain Text to Bulleted Lists in C# with .NET](https://www.textcontrol.com/blog/2025/01/21/convert-plain-text-to-bulleted-lists-in-csharp-with-dotnet/) turns lines that start with a hyphen into list items.

### Write Right-to-Left Paragraphs

Arabic and Hebrew are written from right to left. The writing direction is a paragraph attribute, [ParagraphFormat.Direction](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/direction-property/llms-full.txt), with the values `LeftToRight`, the default, and `RightToLeft` of the [Direction](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/direction/enumeration/llms-full.txt) enumeration. In a right-to-left paragraph, blocks of left-to-right and right-to-left characters are ordered from right to left. The following program adds text from a file to a heading and turns every paragraph after the heading to right to left:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    // Arabic or Hebrew text from a UTF-8 file
    string rightToLeftText = File.ReadAllText("Documents/rtl.txt");
    tx.Text = "Invoice INV-2025-001\r\n" + rightToLeftText;

    // Select everything from the second paragraph to the end of the text
    int start = tx.Paragraphs[2].Start - 1;
    tx.Select(start, tx.Text.Length - start);

    // Right to left, with left and right alignment and tab stops mirrored
    if (tx.Selection.ChangeDirection(Direction.RightToLeft))
    {
        Console.WriteLine("The direction of the selected paragraphs was changed.");
    }

    tx.Save("right-to-left.pdf", StreamType.AdobePDF);
}
```

The code works as follows:

- `Paragraph.Start` is one-based, so 1 is subtracted before the position is passed to `Select`.
- [Selection.ChangeDirection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/selection/changedirection-method/llms-full.txt) sets the direction of all selected paragraphs and returns `true` if at least one paragraph was changed. It also mirrors their alignment, so a left-aligned paragraph becomes right-aligned, and it swaps left and right tab stops. Centered and justified paragraphs keep their alignment.
- Setting `Direction` in a `ParagraphFormat` changes only the direction: a left-aligned paragraph stays left-aligned. Use it when you set the alignment yourself, for example `new ParagraphFormat() { Direction = Direction.RightToLeft, Alignment = HorizontalAlignment.Right }`.

Justified lines with Arabic or Hebrew characters can be filled in another way. [ParagraphFormat.Justification](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/paragraphformat/justification-property/llms-full.txt) decides how the space of a justified line is filled, with a value of [Justification](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/justification/enumeration/llms-full.txt):

| Value | A justified line is filled with |
|---|---|
| `Spaces` (default) | Additional space between the words |
| `Kashida` | Inserted Kashida lines |
| `SpacesAndKashida` | Both |

```csharp
tx.SelectAll();
tx.Selection.ParagraphFormat.Alignment = HorizontalAlignment.Justify;
tx.Selection.ParagraphFormat.Justification = Justification.SpacesAndKashida;
```

For a selection whose paragraphs have different directions, `Direction` returns its default, `LeftToRight`. Spell checking and hyphenation use the language of the text, which you set with `Selection.Culture`, as [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/#insert-formatted-text) shows.

### Next Steps

- [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/llms-full.txt): format characters and use inline styles.
- [Sections](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/sections/llms-full.txt): set the page size, margins and columns.
- [Tables](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/tables/llms-full.txt): arrange content in rows and columns.
- [Text and Paragraph Formatting](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/formatting/llms-full.txt) in the Document Editor: format paragraphs from JavaScript.

---

## Nearby

- **Previous:** [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/llms-full.txt)
- **Next:** [Tables](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/tables/llms-full.txt)
