1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
restructuredtext-lint
=====================
.. image:: https://travis-ci.org/twolfson/restructuredtext-lint.png?branch=master
:target: https://travis-ci.org/twolfson/restructuredtext-lint
:alt: 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.
.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html
.. _`linter`: http://en.wikipedia.org/wiki/Lint_%28software%29
.. _`reST`: `reStructuredText`_
.. _`PyPI`: http://pypi.python.org/
.. _`Sublime Text`: http://sublimetext.com/
Getting Started
---------------
Install the module with: ``pip install restructuredtext_lint``
.. code:: python
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``).
.. code:: console
$ 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`_
- 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
- http://stackoverflow.com/a/16594755
- Please use absolute hyperlinks (e.g. ``https://github.com/twolfson/restructuredtext-lint/blob/master/UNLICENSE``)
.. _`#27`: https://github.com/twolfson/restructuredtext-lint/issues/27
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``
.. _`docutils`: http://docutils.sourceforge.net/
``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
- ``*args`` - Additional arguments to be passed to ``lint``
- ``**kwargs`` - Additional keyword arguments to be passed to ``lint``
.. _`locale.getpreferredencoding`: http://docs.python.org/2/library/locale.html#locale.getpreferredencoding
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`_.
.. _`Sphinx`: http://sphinx-doc.org/
.. _`Sphinx's parser`: Sphinx_
.. _`#29`: https://github.com/twolfson/restructuredtext-lint/issues/29#issuecomment-243456787
https://github.com/sphinx-doc/sphinx/blob/1.3/sphinx/directives/code.py
**sphinx.rst**
.. code:: rst
Hello
=====
World
.. highlight:: python
Hello World!
**sphinx.py**
.. code:: python
# 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
.. code:: python
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
.. _`others by twolfson`: http://twolfson.com/projects
.. _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`_.
.. _UNLICENSE: https://github.com/twolfson/restructuredtext-lint/blob/master/UNLICENSE
|