Skip to main content
Build Status

reStructuredText linter

This was created out of frustration with PyPI; it sucks finding out your reST is invalid after uploading it. It is being developed in junction with a Sublime Text linter.

Getting Started

Install the module with: pip install restructuredtext_lint

import restructuredtext_lint
errors = restructuredtext_lint.lint("""
Hello World
=======
""")

# `errors` will be list of system messages
# [<system_message: <paragraph...><literal_block...>>]
errors[0].message  # Title underline too short.

CLI Utility

For your convenience, we present a CLI utility rst-lint (also available as restructuredtext-lint).

$ rst-lint --help
usage: rst-lint [-h] [--version] [--format {text,json}]
                [--level {debug,info,warning,error,severe}]
                [--rst-prolog RST_PROLOG]
                path [path ...]

Lint reStructuredText files. Returns 0 if all files pass linting, 1 for an
internal error, and 2 if linting failed.

positional arguments:
  path                  File/folder to lint

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --format {text,json}  Format of the output (default: "text")
  --level {debug,info,warning,error,severe}
                        Minimum error level to report (default: "warning")
  --rst-prolog RST_PROLOG
                        reStructuredText content to prepend to all files
                        (useful for substitutions)

$ rst-lint README.rst
WARNING README.rst:2 Title underline too short.

Other tools

restructuredtext-lint is also integrated in other tools. A list can be found and updated in our wiki

https://github.com/twolfson/restructuredtext-lint/wiki/Integration-in-other-tools

PyPI issues

While a document may lint cleanly locally, there can be issues when submitted it to PyPI. Here are some common problems:

  • Usage of non-builtin lexers (e.g. bibtex) will pass locally but not be recognized/parsable on PyPI

    • This is due to PyPI not having a non-builtin lexer installed

    • Please avoid non-builtin lexers to avoid complications

    • For more information, see #27

  • Relative hyperlinks will not work (e.g. ./UNLICENSE)

    • According to Stack Overflow, hyperlinks must use a scheme (e.g. http, https) and that scheme must be whitelisted

    • Please use absolute hyperlinks (e.g. https://github.com/twolfson/restructuredtext-lint/blob/master/UNLICENSE)

Breaking changes in 2.0.0

We removed the --encoding CLI parameter and its correspodning keyword argument.

This was because not using “utf-8” by default was confusing and detracted from the purpose of our tool (#65).

i.e. rst-lint's purpose is to check reST structural elements, not the content itself.

Documentation

restructuredtext-lint exposes a lint and lint_file function

restructuredtext_lint.lint(content, filepath=None, rst_prolog=None)

Lint reStructuredText and return errors

  • content String - reStructuredText to be linted

  • filepath String - Optional path to file, this will be returned as the source

  • rst_prolog String - Optional content to prepend to content, line numbers will be offset to ignore this

Returns:

  • errors List - List of errors

    • Each error is a class from docutils with the following attrs

      • line Integer|None - Line where the error occurred

        • On rare occasions, this will be None (e.g. anonymous link mismatch)

      • source String - filepath provided in parameters

      • level Integer - Level of the warning

        • Levels represent ‘info’: 1, ‘warning’: 2, ‘error’: 3, ‘severe’: 4

      • type String - Noun describing the error level

        • Levels can be ‘INFO’, ‘WARNING’, ‘ERROR’, or ‘SEVERE’

      • message String - Error message

      • full_message String - Error message and source lines where the error occurred

    • It should be noted that level, type, message, and full_message are custom attrs added onto the original system_message

restructuredtext_lint.lint_file(filepath, *args, **kwargs)

Lint a reStructuredText file and return errors

  • filepath String - Path to file for linting

  • *args - Additional arguments to be passed to lint

  • **kwargs - Additional keyword arguments to be passed to lint

Returns: Same structure as restructuredtext_lint.lint

Extension

Under the hood, we leverage docutils for parsing reStructuredText documents. docutils supports adding new directives and roles via register_directive and register_role.

Sphinx

Unfortunately due to customizations in Sphinx’s parser we cannot include all of its directives/roles (see #29). However, we can include some of them as one-offs. Here is an example of adding a directive from Sphinx.

https://github.com/sphinx-doc/sphinx/blob/1.3/sphinx/directives/code.py

sphinx.rst

Hello
=====
World

.. highlight:: python

    Hello World!

sphinx.py

# Load in our dependencies
from docutils.parsers.rst.directives import register_directive
from sphinx.directives.code import Highlight
import restructuredtext_lint

# Load our new directive
register_directive('highlight', Highlight)

# Lint our README
errors = restructuredtext_lint.lint_file('docs/sphinx/README.rst')
print errors[0].message # Error in "highlight" directive: no content permitted.

Examples

Here is an example of all invalid properties

rst = """
Some content.

Hello World
=======
Some more content!
"""
errors = restructuredtext_lint.lint(rst, 'myfile.py')
errors[0].line  # 5
errors[0].source  # myfile.py
errors[0].level  # 2
errors[0].type  # WARNING
errors[0].message  # Title underline too short.
errors[0].full_message  # Title underline too short.
                        #
                        # Hello World
                        # =======

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality.

Testing

Testing can be performed locally via:

# Configure local `rst-lint` to use run from this package
python setup.py develop

# Install development dependencies
pip install -r requirements-dev.txt

# Run our test suite
./test.sh

Donating

Support this project and others by twolfson via donations.

http://twolfson.com/support-me

Unlicense

As of Nov 22 2013, Todd Wolfson has released this repository and its contents to the public domain.

It has been released under the UNLICENSE.

Release files for restructuredtext-lint 2.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for restructuredtext-lint 2.0.2
File Size Uploaded
restructuredtext_lint-2.0.2.tar.gz 17.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for restructuredtext-lint 2.0.2
File Interpreter ABI Platform
restructuredtext_lint-2.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 31.7 kB

Release files / restructuredtext_lint-2.0.2.tar.gz

Download URL restructuredtext_lint-2.0.2.tar.gz
Size 17.5 kB
Tags Source
SHA-256 checksum
How to use checksums
dd25209b9e0b726929d8306339faf723734a3137db382bcf27294fa18a6bc52b
BLAKE2b-256 checksum
How to use checksums
cae6eefcad2228f4124f17e01064428fbcd0ade06a274f3063ce3a126a569d6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / restructuredtext_lint-2.0.2-py3-none-any.whl

Download URL restructuredtext_lint-2.0.2-py3-none-any.whl
Size 14.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
374c0d3e7e0867b2335146a145343ac619400623716b211b9a010c94426bbed7
BLAKE2b-256 checksum
How to use checksums
af63ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

2.0.2 This release

2 release files

2.0.1

2 release files

2.0.0

1 release file

1.4.1

1 release file

1.4.0

1 release file

1.3.2

1 release file

1.3.1

1 release file

1.3.0

1 release file

1.2.2

1 release file

1.2.1

1 release file

1.2.0

1 release file

1.1.3

1 release file

1.1.2

1 release file

1.1.1

1 release file

1.1.0

1 release file

1.0.1

1 release file

1.0.0

1 release file

0.18.0

1 release file

0.17.0

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.3

2 release files

0.14.2

2 release files

0.14.1

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.4

2 release files

0.12.3

2 release files

0.12.2

2 release files

0.11.3

2 release files

0.11.2

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page