# Spell Checking and Hyphenation

> Proof documents with ServerTextControl: connect TX Spell .NET, read and correct MisspelledWords, set the language of text and hyphenate with HyphenateWord.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Document Processing > Spell Checking and Hyphenation
- **2953 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/spell-checking/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/spell-checking/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/spell-checking/llms-full.txt

---

A batch of generated letters can be proofread before it's sent, and a PDF with narrow columns looks better when long words are hyphenated at the end of a line. `ServerTextControl` checks spelling and hyphenates words with the help of TX Spell .NET. Your code turns both on, reads and corrects the misspelled words of every part of a document, sets the language that decides which dictionary is used and adjusts where words are divided.

Spell checking while users type in the browser, with dialog boxes and user dictionaries, is described in [Spell Checking](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/spell-checking/llms-full.txt) in the Document Editor section.

### What You Need

Spell checking and hyphenation are calculated by TX Spell .NET, a separate Text Control product. For .NET applications, it's available as the NuGet package `TXTextControl.TXSpell.Core.SDK`, which copies its *Dictionaries*, *HyphenationLists*, *LanguageRecognition* and *SynonymLists* folders into the output of the project. TX Spell .NET supports the Hunspell dictionaries of OpenOffice.org, which cover more than 60 languages, each under its own license terms. For licensing questions, contact the [Text Control sales team](https://www.textcontrol.com/contact/).

A spell checking component is connected with [ServerTextControl.SpellChecker](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/spellchecker-property/llms-full.txt), which must be set to a TX Spell .NET object; the TX Spell .NET documentation describes how to create it. When no component is connected, the property is `null`. With a connected component, three properties of `ServerTextControl` take effect:

| Property | When `true` |
|---|---|
| [IsSpellCheckingEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/isspellcheckingenabled-property/llms-full.txt) | The text is checked, and the misspelled words of the document are collected in `MisspelledWords` |
| [IsHyphenationEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/ishyphenationenabled-property/llms-full.txt) | Words that don't fit at the end of a line are divided |
| [IsLanguageDetectionEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/islanguagedetectionenabled-property/llms-full.txt) | A language is detected for all text that has the neutral language |

Hyphenation divides words at the end of a line, so it changes where the lines and the pages of a document break. Set `IsHyphenationEnabled` before you save the document in a paginated format such as PDF.

### Read and Correct Misspelled Words

Each text part of a document has a [MisspelledWordCollection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledwordcollection/llms-full.txt): [ServerTextControl.MisspelledWords](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/misspelledwords-property/llms-full.txt) for the main text and [IFormattedText.MisspelledWords](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/iformattedtext/misspelledwords-property/llms-full.txt) for each part in `TextParts`. The following class prints the misspelled words of all text parts and replaces those for which a correction is known. Call it with a `ServerTextControl` whose `SpellChecker` is connected and which contains the document to check:

```csharp
using TXTextControl;

public static class Proofreader
{
    public static void CorrectSpelling(ServerTextControl tx, IDictionary<string, string> corrections)
    {
        tx.IsSpellCheckingEnabled = true;

        // The main text, text frames, headers and footers
        foreach (IFormattedText textPart in tx.TextParts)
        {
            MisspelledWordCollection words = textPart.MisspelledWords;

            Console.WriteLine($"{textPart.GetType().Name}: {words.GetCount(MisspelledWordKind.Normal)} misspelled, " +
                $"{words.GetCount(MisspelledWordKind.Duplicate)} repeated");

            // From the last word to the first, because Remove changes the collection
            for (int number = words.Count; number >= 1; number--)
            {
                MisspelledWord word = words[number];
                string language = word.Culture?.Name ?? "neutral";

                Console.WriteLine($"  {word.Text} at {word.Start} ({language}), repeated: {word.IsDuplicate}");

                if (corrections.TryGetValue(word.Text, out string? corrected))
                {
                    // Replaces the word in the document with the corrected text
                    words.Remove(word, corrected);
                }
            }
        }
    }
}
```

The code works as follows:

- [GetCount](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledwordcollection/getcount-method/llms-full.txt) counts the words of a [MisspelledWordKind](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledwordkind/enumeration/llms-full.txt): `Normal` for misspelled words, `Duplicate` for a correctly spelled word that repeats the word in front of it, `Ignored` for ignored words or `All`.
- The indexer [Item](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledwordcollection/item-property/llms-full.txt) takes a number from 1 to `Count`, in the order of the text.
- A [MisspelledWord](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/llms-full.txt) has its [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/text-property/llms-full.txt), the one-based [Start](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/start-property/llms-full.txt) position, its [Length](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/length-property/llms-full.txt) and its [Culture](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/culture-property/llms-full.txt), which is `null` when the word has no specific language. [IsDuplicate](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/isduplicate-property/llms-full.txt) marks a repeated word.
- [Remove](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledwordcollection/remove-method/llms-full.txt) with a corrected text replaces the word in the document. Without a text, it removes only the entry from the collection and leaves the word as it is.

To accept a word without changing it, set [IsIgnored](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/isignored-property/llms-full.txt) to `true`: the word stays in the collection with the kind `Ignored`. [Ignore](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledwordcollection/ignore-method/llms-full.txt) replaces the text of a word and marks it as ignored in one step. [GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledwordcollection/getitem-method/llms-full.txt) with a zero-based text position returns the misspelled word at that position, or the next one after it.

To exclude the text of a field from spell checking, for example a field with a customer name, set [TextField.IsSpellCheckingEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/textfield/isspellcheckingenabled-property/llms-full.txt) to `false`.

### Set the Language of Text

Spell checking and hyphenation use the dictionary of the language of the text. The language is a character attribute, so one document can contain text in several languages:

- **For a piece of text,** set [Selection.Culture](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/selection/culture-property/llms-full.txt) to a `CultureInfo`, as the example of [Insert Formatted Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/#insert-formatted-text) does for a German paragraph. The default is `null`, the neutral language.
- **For all text of a style,** set [FormattingStyle.Culture](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/formattingstyle/culture-property/llms-full.txt) of a paragraph or inline style.
- **For text without a language,** turn on `IsLanguageDetectionEnabled`. The language is then detected for all text parts with the neutral language.

### Hyphenate Words

With `IsHyphenationEnabled` set to `true`, the [HyphenateWord](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/hyphenateword-event/llms-full.txt) event occurs for each word that doesn't fit at the end of a line. Its [HyphenateWordEventArgs](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/hyphenatewordeventargs/llms-full.txt) contain the position at which the connected spell checker divides the word, and your handler can change it. The following class turns hyphenation on and logs each word that is hyphenated:

```csharp
using TXTextControl;

public static class Hyphenation
{
    public static void Enable(ServerTextControl tx)
    {
        tx.HyphenateWord += (sender, e) =>
        {
            string language = e.Culture?.Name ?? "neutral";
            Console.WriteLine($"{e.Word} ({language}): divided after {e.DividePos} of at most {e.MaxDividePos} characters");
        };

        tx.IsHyphenationEnabled = true;
    }
}
```

The code works as follows:

- [Word](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/hyphenatewordeventargs/word-property/llms-full.txt) is the word to hyphenate and [Culture](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/hyphenatewordeventargs/culture-property/llms-full.txt) its language.
- [MaxDividePos](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/hyphenatewordeventargs/maxdividepos-property/llms-full.txt) is the number of characters that fit on the line: with 3, at most the first 3 characters stay on it.
- [DividePos](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/hyphenatewordeventargs/dividepos-property/llms-full.txt) is the position calculated by the connected spell checker, or 0 without one. The word is divided at this position if it's less than or equal to `MaxDividePos`. To divide a word elsewhere, for example according to rules of your own, the handler sets `DividePos` to another position.

To allow a word to be divided at one position only, insert a non-visible hyphen there with `ControlChars.NonVisibleHyphen`, as [Insert Special Characters](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/#insert-special-characters) describes. The hyphen appears only when the word is broken at that position.

### Check Spelling Without TX Spell .NET

When `IsSpellCheckingEnabled` is `true` and no component is connected with `SpellChecker`, `ServerTextControl` raises [SpellCheckText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/spellchecktext-event/llms-full.txt) whenever text has changed and must be checked. Your handler checks the text with a spell checker of its own:

- [SpellCheckTextEventArgs.Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/spellchecktexteventargs/text-property/llms-full.txt) is the text to check, and [Culture](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/spellchecktexteventargs/culture-property/llms-full.txt) its language.
- The handler sets [MisspelledWords](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/spellchecktexteventargs/misspelledwords-property/llms-full.txt) to an array of `MisspelledWord` objects, one for each misspelled word the text contains. The [MisspelledWord constructor](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/misspelledword/constructor/llms-full.txt) takes the one-based start position and the length of the word.

[Events](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/events/llms-full.txt) lists `SpellCheckText` with the other events of `ServerTextControl`.

### Next Steps

- [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/llms-full.txt): set the language and other attributes of text.
- [Spell Checking](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/spell-checking/llms-full.txt) in the Document Editor: check spelling while users type.
- [Events](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/events/llms-full.txt): the proofing events and all other events of `ServerTextControl`.

---

## Nearby

- **Previous:** [Document Protection](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/protection/llms-full.txt)
- **Next:** [Pages](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/pages/llms-full.txt)
