# ReText: four markup formats claimed, two installed by pip

> ReText is a Python and PyQt6 desktop editor that puts the Markups converter behind a source pane and a live preview. The distance between the four formats it advertises and the two that pip actually installs is the part worth checking before adoption.

**retext-project/retext** — ReText: Simple but powerful editor for Markdown and reStructuredText

- Repository: https://github.com/retext-project/retext
- Stars: 2,065 · Forks: 215
- Language: Python
- License: GPL-2.0
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/retext-project-retext

## A PyQt6 shell over the Markups conversion library

ReText is a desktop editor for markup files written in Python. PyQt6 supplies the window, the menus, the preview pane and the file handling; the parsing and rendering come from a separate library called Markups, which covers Markdown, reStructuredText, Textile and AsciiDoc. Splitting it that way keeps the format work in its own package, and the editor is one consumer of it.

Adding a format outside those four means writing a Python module, which the pymarkups documentation describes, so extension happens at the library layer rather than in a plugin directory inside ReText.

Three descriptions of the same project do not match. The repository description calls ReText an editor for Markdown and reStructuredText, the README adds Textile and AsciiDoc, and the description field in pyproject.toml goes back to a simple editor for Markdown and reStructuredText. The version field there still reads 8.1.0 while the last push was on 2026-09-24 and the repository is not archived.

## The default install carries two markups, not four

The command in the README resolves the dependency block in pyproject.toml, and that block names two extras and nothing else from the format world:

```toml
requires-python = ">=3.9"
dependencies = [
  "Markups[markdown,restructuredtext]>=4.0",
  "Pygments",
  "PyQt6",
]
```

Textile is absent from those extras and AsciiDoc does not appear in them at all, so someone who takes the four-format claim at face value and opens a Textile file after a plain install has no conversion path for it. The README's own remedy is to install Markups by hand with the extras syntax:

```bash
pip3 install Markups[markdown,restructuredtext,textile]
```

That command settles Textile and leaves AsciiDoc to whatever extra name Markups uses, which the README never spells out. Doing it by hand also means pip never sees the pyenchant, chardet or PyQt6-WebEngine additions, so a manual Markups install hands you formats without the editor extras the package would have pulled.

The cost is small for a reader who knows about extras and confusing for one who does not. An install that reports ReText as installed successfully leaves exactly two markup parsers underneath, not four.

## Installing on Python 3.9 and running a clone directly

Python 3.9 or later is the floor, stated in the README and enforced by requires-python in pyproject.toml. From a fresh environment:

```bash
pip3 install ReText
```

That single command resolves PyQt6 and Markups 4.0 or later on its own, and what it leaves behind is a launcher named retext, declared under gui-scripts:

```toml
[project.gui-scripts]
retext = "ReText.__main__:main"
```

Two other routes exist for readers who would rather not have pip writing into system Python. The README points at a virtual environment, and it also points at the tarball on PyPI or a clone of the repository, which starts without being installed at all:

```bash
./retext.py
```

A clone differs from an installed copy in a way that shows up immediately: the compiled translation files are not there. The README says they arrive already compiled in the tarball, while a checkout carries only the source files and needs the Qt compiler run over them first.

## A missing Qt compiler only logs, the build continues

Project metadata moved into pyproject.toml, but setup.py stayed behind for four custom setuptools commands, and one of those runs the Qt translation compiler. The custom build class puts build_translations in front of the standard sub_commands, so every build and every sdist compiles the .ts files first:

```python
for ts_file in glob(join('ReText', 'locale', '*.ts')):
    check_call(('lrelease', ts_file), env=environment)
```

The environment pins Qt 6 and asks qmake6 where the Qt 6 binaries are:

```python
environment = dict(os.environ, QT_SELECT='6')
qt6_path = check_output(('qmake6', '-query', 'QT_INSTALL_BINS'))
```

Here is where it bites. A missing qmake6 raises an OSError that is logged, after which execution continues into the loop, and a failing lrelease lands in an exception handler that logs and then breaks out of the loop rather than stopping anything:

```python
logging.exception('Failed to build translations:')
```

So a source install on a machine without Qt developer tools finishes, installs and starts, with the rest of the .ts files never converted and nothing in the setup output saying the interface is now untranslated. On Debian-based systems the missing binary sits at /usr/lib/qt6/bin/lrelease, shipped by the qt6-l10n-tools package, and finished translation files can also be picked up from /usr/share/retext/.

## One launcher, and the short list of files that ship

The build-system block pins the setuptools backend at 62.4 or later, and every packaging decision below lives in that same file. The repository root is small:

```
.git-blame-ignore-revs
.github/
.gitignore
LICENSE_GPL
MANIFEST.in
README.md
ReText/
changelog.md
configuration.md
data/
pyproject.toml
retext.py
setup.py
tests/
```

Because include-package-data is false in pyproject.toml, nothing is swept into the package automatically. Only three groups of files inside ReText are declared, and that declaration is explicit:

```toml
[tool.setuptools.package-data]
ReText = ["icons/*.png", "icons/*.svg", "locale/*.qm"]
```

Desktop integration comes from a separate data-files block: the .desktop entry lands in share/applications, the scalable icon in share/icons/hicolor/scalable/apps, the metainfo file in share/metainfo. Drop a new asset into the ReText directory and it stays behind until that list changes, since MANIFEST.in at the root does not widen it.

The package identifier is GPL-2.0-or-later, LICENSE_GPL at the root holds the text, and the classifier line repeats GNU General Public License v2 or later, so anyone shipping a modified build passes those copyleft terms along with it.

## Settings keys live in configuration.md, which the README skips

configuration.md sits at the repository root and the README never mentions it. No settings key, no default directory, no theme name and no way to change the preview width appears in the README, and the only pointer it gives for anything past installation is the wiki.

That silence is more annoying in a desktop application than in a library, because a settings dialog can be opened and read while a README claim cannot be checked at all. Nothing in the README says where ReText stores its configuration or which format that store uses.

Other root entries are equally undocumented in prose and equally informative. MANIFEST.in is the list a source archive reads, .git-blame-ignore-revs exists because the history carries bulk reformats, and tests/ holds the suite behind the GitHub Actions badge at the top of the README, a badge that never states what it covers.

## Three extras switch on spellcheck, encoding detection and WebEngine

The recommended features are declared as extras rather than installed:

```toml
spellcheck = ["pyenchant"]
encoding-detection = ["chardet"]
webengine = ["PyQt6-WebEngine"]
```

The README assigns each one a job: pyenchant for spell checking support, chardet for encoding detection support, and PyQt6-WebEngine for a preview engine with JavaScript support, which it calls more capable than the default. None of the three arrives with a base install, so the out-of-the-box editor has no spell checking and the default preview engine.

Pygments sits in the required dependency list with no comment and no mention anywhere in the README, so its purpose is undocumented. That matters for anyone trimming the dependency set for a small machine, because the file gives no basis for deciding whether the highlighter is needed.

What remains on a default install is Markups, Pygments and PyQt6, for an editor whose own README treats three of its features as things you install yourself.

## Converting without the window through Markups alone

Every format ReText can display is converted by Markups before any Qt code draws it. A build script that needs HTML from Markdown or reStructuredText can depend on the same extras ReText depends on and skip PyQt6, the desktop data files and the translation step:

```toml
"Markups[markdown,restructuredtext]>=4.0",
```

The trade runs the other way too. Formats beyond the four built-ins are Python modules documented by pymarkups, spell checking needs the pyenchant extra, and the JavaScript-capable preview needs PyQt6-WebEngine, so what ReText adds over the library is editing, checking and rendering rather than conversion.

What ReText is not is a project editor: nothing in the README describes symbol navigation, refactoring or version control integration, and pyproject.toml files the project under Topic :: Text Editors. A team that already lives inside an IDE gains little by moving a plain prose file into this window.

## Conclusion

ReText suits a writer who wants one Qt window for Markdown and reStructuredText, a live preview and spell checking, and who prefers a virtual environment to writing into system Python. It fits badly for build scripts and CI, where PyQt6 buys nothing over converting with Markups directly, and for Textile or AsciiDoc users, since a plain install brings neither parser. Before adopting, install Markups by hand with the textile extra, then open one document in each format you plan to keep and confirm the preview renders it as you expect.

## FAQ

### Which markup formats does ReText support out of the box?

The README names Markdown, reStructuredText, Textile and AsciiDoc, while the dependency block in pyproject.toml installs Markups[markdown,restructuredtext]>=4.0, so a plain install carries only Markdown and reStructuredText. Textile needs the Markups extra installed by hand, and the README does not name the extra for AsciiDoc.

### What does ReText need before it will start?

Python 3.9 or later, PyQt6 and Markups 4.0 or later. The command pip3 install ReText resolves those by itself, and the README also points at a virtual environment, at the tarball on PyPI, or at running ./retext.py straight from a clone.

### How do I get spell checking and the JavaScript preview in ReText?

Install the extras: spellcheck pulls pyenchant, encoding-detection pulls chardet, and webengine pulls PyQt6-WebEngine, which the README calls a more capable preview engine with JavaScript support. None of them is part of the default dependency list.

### Does building ReText from source need Qt developer tools?

Yes for translations: setup.py runs lrelease over ReText/locale/*.ts and queries qmake6 for the Qt 6 binary path, and on Debian-based systems that compiler comes from the qt6-l10n-tools package at /usr/lib/qt6/bin/lrelease. Failures are logged and the loop breaks, so the build completes with the remaining translation files uncompiled.

### Can ReText open a markup format it does not ship with?

New formats are added at the library layer, as Python modules described in the pymarkups documentation, rather than through a plugin directory inside ReText. Anything outside the built-ins depends on the Markups version you install.

## Sources

- [Issues](https://github.com/retext-project/retext/issues)
- [License: GPL-2.0](https://github.com/retext-project/retext/blob/master/LICENSE)
- [README](https://github.com/retext-project/retext/blob/master/README.md)
- [Releases](https://github.com/retext-project/retext/releases)
- [retext-project/retext on GitHub](https://github.com/retext-project/retext)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/retext-project-retext
