GitHub - twolfson/restructuredtext-lint: reStructuredText linter (original) (raw)
restructuredtext-lint
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}] [--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.
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 - 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
* http://stackoverflow.com/a/16594755 - 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.
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
* lineInteger|None
- Line where the error occurred
* On rare occasions, this will beNone
(e.g. anonymous link mismatch)
* sourceString
-filepath
provided in parameters
* levelInteger
- Level of the warning
* Levels represent 'info': 1, 'warning': 2, 'error': 3, 'severe': 4
* typeString
- Noun describing the error level
* Levels can be 'INFO', 'WARNING', 'ERROR', or 'SEVERE'
* messageString
- Error message
* full_messageString
- Error message and source lines where the error occurred - It should be noted that
level
,type
,message
, andfull_message
are custom attrs added onto the originalsystem_message
- Each error is a class from docutils with the following attrs
restructuredtext_lint.lint_file(filepath, encoding=None, *args, **kwargs)
Lint a reStructuredText file and return errors
- filepath
String
- Path to file for linting - encoding
String
- Encoding to read file in as- When
None
is 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
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. Test via nosetests
.
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.