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.
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.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}] [--encoding ENCODING]
[--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")
--encoding ENCODING Encoding of the input file (e.g. "utf-8")
--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.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
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 - 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)
- According to Stack Overflow, hyperlinks must use a scheme (e.g.
restructuredtext-lint exposes a lint and lint_file function
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)
- On rare occasions, this will be
- source
String-filepathprovided 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
- line
- It should be noted that
level,type,message, andfull_messageare custom attrs added onto the originalsystem_message
- Each error is a class from docutils with the following attrs
Lint a reStructuredText file and return errors
- filepath
String- Path to file for linting - encoding
String- Encoding to read file in as- When
Noneis provided, it will use OS default as provided by locale.getpreferredencoding - The list of supported encodings can be found at http://docs.python.org/2/library/codecs.html#standard-encodings
- When
*args- Additional arguments to be passed tolint**kwargs- Additional keyword arguments to be passed tolint
Returns: Same structure as restructuredtext_lint.lint
Under the hood, we leverage docutils for parsing reStructuredText documents. docutils supports adding new directives and roles via register_directive and register_role.
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.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
# =======In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Test via nosetests.
Support this project and others by twolfson via donations.
http://twolfson.com/support-me
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.