Hello community,

here is the log from the commit of package rstcheck for openSUSE:Factory 
checked in at 2017-06-24 08:34:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rstcheck (Old)
 and      /work/SRC/openSUSE:Factory/.rstcheck.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rstcheck"

Sat Jun 24 08:34:41 2017 rev:3 rq:505844 version:3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/rstcheck/rstcheck.changes        2016-07-14 
09:50:28.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.rstcheck.new/rstcheck.changes   2017-06-24 
08:34:58.064032837 +0200
@@ -1,0 +2,12 @@
+Fri Jun 16 08:16:09 UTC 2017 - [email protected]
+
+- bump to verion 3.1
+- Add support for checking XML code blocks (thanks to Sameer Singh).
+- Support UTF-8 byte order marks (BOM). Previously, ``docutils`` would
+  interpret the BOM as a visible character, which would lead to false 
+  positives about underlines being too short.
+- Optionally support Sphinx 1.5. Sphinx support will be enabled if Sphinx is
+  installed.
+- Support loading settings from configuration files.
+
+-------------------------------------------------------------------

Old:
----
  rstcheck-1.5.1.tar.gz

New:
----
  rstcheck-3.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rstcheck.spec ++++++
--- /var/tmp/diff_new_pack.TlvQu4/_old  2017-06-24 08:34:58.523967802 +0200
+++ /var/tmp/diff_new_pack.TlvQu4/_new  2017-06-24 08:34:58.523967802 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package rstcheck
 #
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,20 +17,19 @@
 
 
 Name:           rstcheck
-Version:        1.5.1
+Version:        3.1
 Release:        0
 Summary:        Checks syntax of rST and code blocks nested within it
 License:        MIT
 Group:          Development/Languages/Python
 Url:            https://github.com/myint/rstcheck
-Source:         
http://pypi.python.org/packages/source/r/rstcheck/rstcheck-%{version}.tar.gz
+Source:         
https://files.pythonhosted.org/packages/source/r/rstcheck/rstcheck-%{version}.tar.gz
 BuildRequires:  python3-Sphinx
 BuildRequires:  python3-devel
 BuildRequires:  python3-docutils
 BuildRequires:  python3-setuptools
 Requires:       python3-Sphinx
 Requires:       python3-docutils
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildArch:      noarch
 
 %description

++++++ rstcheck-1.5.1.tar.gz -> rstcheck-3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/LICENSE new/rstcheck-3.1/LICENSE
--- old/rstcheck-1.5.1/LICENSE  2015-08-16 20:15:34.000000000 +0200
+++ new/rstcheck-3.1/LICENSE    2016-07-24 23:24:23.000000000 +0200
@@ -1,4 +1,4 @@
-Copyright (C) 2013-2015 Steven Myint
+Copyright (C) 2013-2016 Steven Myint
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/PKG-INFO new/rstcheck-3.1/PKG-INFO
--- old/rstcheck-1.5.1/PKG-INFO 2016-03-29 17:13:30.000000000 +0200
+++ new/rstcheck-3.1/PKG-INFO   2017-03-08 17:00:34.000000000 +0100
@@ -1,7 +1,7 @@
 Metadata-Version: 1.1
 Name: rstcheck
-Version: 1.5.1
-Summary: Checks syntax of reStructuredText and code blocks nested within it.
+Version: 3.1
+Summary: Checks syntax of reStructuredText and code blocks nested within it
 Home-page: https://github.com/myint/rstcheck
 Author: UNKNOWN
 Author-email: UNKNOWN
@@ -17,12 +17,15 @@
         Checks syntax of reStructuredText and code blocks nested within it.
         
         
+        .. contents::
+        
+        
         Installation
         ============
         
         From pip::
         
-            $ pip install --upgrade rstcheck
+            $ pip install rstcheck
         
         
         Supported languages in code blocks
@@ -33,6 +36,7 @@
         - C (C99)
         - C++ (C++11)
         - JSON
+        - XML
         - Python
         - reStructuredText
         
@@ -42,13 +46,13 @@
         
         With bad Python syntax:
         
-        .. code-block:: rst
+        .. code:: rst
         
             ====
             Test
             ====
         
-            .. code-block:: python
+            .. code:: python
         
                 print(
         
@@ -59,13 +63,13 @@
         
         With bad C++ syntax:
         
-        .. code-block:: rst
+        .. code:: rst
         
             ====
             Test
             ====
         
-            .. code-block:: cpp
+            .. code:: cpp
         
                 int main()
                 {
@@ -79,7 +83,7 @@
         
         With bad syntax in the reStructuredText document itself:
         
-        .. code-block:: rst
+        .. code:: rst
         
             ====
             Test
@@ -175,12 +179,26 @@
             $ rstcheck docs/foo/bar.rst
         
         
+        Sphinx
+        ======
+        
+        To enable Sphinx::
+        
+            $ pip install sphinx
+        
+        The installed Sphinx version must be at least 1.5.
+        
+        To check that Sphinx support is enabled::
+        
+            $ rstcheck -h | grep 'Sphinx is enabled'
+        
+        
         Usage in Vim
         ============
         
         To check reStructuredText in Vim using Syntastic_:
         
-        .. code-block:: vim
+        .. code:: vim
         
             let g:syntastic_rst_checkers = ['rstcheck']
         
@@ -200,6 +218,44 @@
         Note that this does not load any configuration as that would mutate the
         ``docutils`` registries.
         
+        
+        History
+        =======
+        
+        3.1 (2017-03-08)
+        ----------------
+        
+        - Add support for checking XML code blocks (thanks to Sameer Singh).
+        
+        3.0.1 (2017-03-01)
+        ------------------
+        
+        - Support UTF-8 byte order marks (BOM). Previously, ``docutils`` would
+          interpret the BOM as a visible character, which would lead to false 
positives
+          about underlines being too short.
+        
+        3.0 (2016-12-19)
+        ----------------
+        
+        - Optionally support Sphinx 1.5. Sphinx support will be enabled if 
Sphinx is
+          installed.
+        
+        2.0 (2015-07-27)
+        ----------------
+        
+        - Support loading settings from configuration files.
+        
+        1.0 (2015-03-14)
+        ----------------
+        
+        - Add Sphinx support.
+        
+        0.1 (2013-12-02)
+        ----------------
+        
+        - Initial version.
+        
+        
         .. rstcheck: ignore-language=cpp,python,rst
         
 Keywords: restructuredtext,lint,check,pypi,readme,rst,analyze
@@ -211,4 +267,5 @@
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: Topic :: Software Development :: Quality Assurance
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/README.rst new/rstcheck-3.1/README.rst
--- old/rstcheck-1.5.1/README.rst       2016-01-24 19:36:55.000000000 +0100
+++ new/rstcheck-3.1/README.rst 2017-03-08 16:59:53.000000000 +0100
@@ -9,12 +9,15 @@
 Checks syntax of reStructuredText and code blocks nested within it.
 
 
+.. contents::
+
+
 Installation
 ============
 
 From pip::
 
-    $ pip install --upgrade rstcheck
+    $ pip install rstcheck
 
 
 Supported languages in code blocks
@@ -25,6 +28,7 @@
 - C (C99)
 - C++ (C++11)
 - JSON
+- XML
 - Python
 - reStructuredText
 
@@ -34,13 +38,13 @@
 
 With bad Python syntax:
 
-.. code-block:: rst
+.. code:: rst
 
     ====
     Test
     ====
 
-    .. code-block:: python
+    .. code:: python
 
         print(
 
@@ -51,13 +55,13 @@
 
 With bad C++ syntax:
 
-.. code-block:: rst
+.. code:: rst
 
     ====
     Test
     ====
 
-    .. code-block:: cpp
+    .. code:: cpp
 
         int main()
         {
@@ -71,7 +75,7 @@
 
 With bad syntax in the reStructuredText document itself:
 
-.. code-block:: rst
+.. code:: rst
 
     ====
     Test
@@ -167,12 +171,26 @@
     $ rstcheck docs/foo/bar.rst
 
 
+Sphinx
+======
+
+To enable Sphinx::
+
+    $ pip install sphinx
+
+The installed Sphinx version must be at least 1.5.
+
+To check that Sphinx support is enabled::
+
+    $ rstcheck -h | grep 'Sphinx is enabled'
+
+
 Usage in Vim
 ============
 
 To check reStructuredText in Vim using Syntastic_:
 
-.. code-block:: vim
+.. code:: vim
 
     let g:syntastic_rst_checkers = ['rstcheck']
 
@@ -192,4 +210,42 @@
 Note that this does not load any configuration as that would mutate the
 ``docutils`` registries.
 
+
+History
+=======
+
+3.1 (2017-03-08)
+----------------
+
+- Add support for checking XML code blocks (thanks to Sameer Singh).
+
+3.0.1 (2017-03-01)
+------------------
+
+- Support UTF-8 byte order marks (BOM). Previously, ``docutils`` would
+  interpret the BOM as a visible character, which would lead to false positives
+  about underlines being too short.
+
+3.0 (2016-12-19)
+----------------
+
+- Optionally support Sphinx 1.5. Sphinx support will be enabled if Sphinx is
+  installed.
+
+2.0 (2015-07-27)
+----------------
+
+- Support loading settings from configuration files.
+
+1.0 (2015-03-14)
+----------------
+
+- Add Sphinx support.
+
+0.1 (2013-12-02)
+----------------
+
+- Initial version.
+
+
 .. rstcheck: ignore-language=cpp,python,rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/rstcheck.egg-info/PKG-INFO 
new/rstcheck-3.1/rstcheck.egg-info/PKG-INFO
--- old/rstcheck-1.5.1/rstcheck.egg-info/PKG-INFO       2016-03-29 
17:13:30.000000000 +0200
+++ new/rstcheck-3.1/rstcheck.egg-info/PKG-INFO 2017-03-08 17:00:33.000000000 
+0100
@@ -1,7 +1,7 @@
 Metadata-Version: 1.1
 Name: rstcheck
-Version: 1.5.1
-Summary: Checks syntax of reStructuredText and code blocks nested within it.
+Version: 3.1
+Summary: Checks syntax of reStructuredText and code blocks nested within it
 Home-page: https://github.com/myint/rstcheck
 Author: UNKNOWN
 Author-email: UNKNOWN
@@ -17,12 +17,15 @@
         Checks syntax of reStructuredText and code blocks nested within it.
         
         
+        .. contents::
+        
+        
         Installation
         ============
         
         From pip::
         
-            $ pip install --upgrade rstcheck
+            $ pip install rstcheck
         
         
         Supported languages in code blocks
@@ -33,6 +36,7 @@
         - C (C99)
         - C++ (C++11)
         - JSON
+        - XML
         - Python
         - reStructuredText
         
@@ -42,13 +46,13 @@
         
         With bad Python syntax:
         
-        .. code-block:: rst
+        .. code:: rst
         
             ====
             Test
             ====
         
-            .. code-block:: python
+            .. code:: python
         
                 print(
         
@@ -59,13 +63,13 @@
         
         With bad C++ syntax:
         
-        .. code-block:: rst
+        .. code:: rst
         
             ====
             Test
             ====
         
-            .. code-block:: cpp
+            .. code:: cpp
         
                 int main()
                 {
@@ -79,7 +83,7 @@
         
         With bad syntax in the reStructuredText document itself:
         
-        .. code-block:: rst
+        .. code:: rst
         
             ====
             Test
@@ -175,12 +179,26 @@
             $ rstcheck docs/foo/bar.rst
         
         
+        Sphinx
+        ======
+        
+        To enable Sphinx::
+        
+            $ pip install sphinx
+        
+        The installed Sphinx version must be at least 1.5.
+        
+        To check that Sphinx support is enabled::
+        
+            $ rstcheck -h | grep 'Sphinx is enabled'
+        
+        
         Usage in Vim
         ============
         
         To check reStructuredText in Vim using Syntastic_:
         
-        .. code-block:: vim
+        .. code:: vim
         
             let g:syntastic_rst_checkers = ['rstcheck']
         
@@ -200,6 +218,44 @@
         Note that this does not load any configuration as that would mutate the
         ``docutils`` registries.
         
+        
+        History
+        =======
+        
+        3.1 (2017-03-08)
+        ----------------
+        
+        - Add support for checking XML code blocks (thanks to Sameer Singh).
+        
+        3.0.1 (2017-03-01)
+        ------------------
+        
+        - Support UTF-8 byte order marks (BOM). Previously, ``docutils`` would
+          interpret the BOM as a visible character, which would lead to false 
positives
+          about underlines being too short.
+        
+        3.0 (2016-12-19)
+        ----------------
+        
+        - Optionally support Sphinx 1.5. Sphinx support will be enabled if 
Sphinx is
+          installed.
+        
+        2.0 (2015-07-27)
+        ----------------
+        
+        - Support loading settings from configuration files.
+        
+        1.0 (2015-03-14)
+        ----------------
+        
+        - Add Sphinx support.
+        
+        0.1 (2013-12-02)
+        ----------------
+        
+        - Initial version.
+        
+        
         .. rstcheck: ignore-language=cpp,python,rst
         
 Keywords: restructuredtext,lint,check,pypi,readme,rst,analyze
@@ -211,4 +267,5 @@
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: Topic :: Software Development :: Quality Assurance
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/rstcheck.egg-info/requires.txt 
new/rstcheck-3.1/rstcheck.egg-info/requires.txt
--- old/rstcheck-1.5.1/rstcheck.egg-info/requires.txt   2016-03-29 
17:13:30.000000000 +0200
+++ new/rstcheck-3.1/rstcheck.egg-info/requires.txt     2017-03-08 
17:00:33.000000000 +0100
@@ -1,2 +1 @@
-docutils
-sphinx
+docutils >= 0.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/rstcheck.py 
new/rstcheck-3.1/rstcheck.py
--- old/rstcheck-1.5.1/rstcheck.py      2016-03-29 17:12:36.000000000 +0200
+++ new/rstcheck-3.1/rstcheck.py        2017-03-08 16:57:21.000000000 +0100
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# Copyright (C) 2013-2015 Steven Myint
+# Copyright (C) 2013-2016 Steven Myint
 #
 # Permission is hereby granted, free of charge, to any person obtaining
 # a copy of this software and associated documentation files (the
@@ -37,9 +37,11 @@
 import multiprocessing
 import os
 import re
+import shutil
 import subprocess
 import sys
 import tempfile
+from xml.etree import ElementTree
 
 try:
     import configparser
@@ -53,24 +55,36 @@
 import docutils.utils
 import docutils.writers
 
-import sphinx
-import sphinx.directives
-import sphinx.domains.c
-import sphinx.domains.cpp
-import sphinx.domains.javascript
-import sphinx.domains.python
-import sphinx.domains.std
-import sphinx.roles
+try:
+    import sphinx
+    SPHINX_INSTALLED = sphinx.version_info >= (1, 5)
+except ImportError:
+    SPHINX_INSTALLED = False
 
+if SPHINX_INSTALLED:
+    import sphinx.application
+    import sphinx.directives
+    import sphinx.domains.c
+    import sphinx.domains.cpp
+    import sphinx.domains.javascript
+    import sphinx.domains.python
+    import sphinx.domains.std
+    import sphinx.roles
 
-__version__ = '1.5.1'
 
+__version__ = '3.1'
 
-SPHINX_CODE_BLOCK_DELTA = -1 if sphinx.version_info >= (1, 3) else 0
+
+if SPHINX_INSTALLED:
+    SPHINX_CODE_BLOCK_DELTA = -1
 
 RSTCHECK_COMMENT_RE = re.compile(r'\.\. rstcheck:')
 
 
+# This is for the cases where code in a readme uses includes in that directory.
+INCLUDE_FLAGS = ['-I.', '-I..']
+
+
 class Error(Exception):
 
     """rstcheck exception."""
@@ -80,6 +94,45 @@
         Exception.__init__(self, message)
 
 
+class CodeBlockDirective(docutils.parsers.rst.Directive):
+
+    """Code block directive."""
+
+    has_content = True
+    optional_arguments = 1
+
+    def run(self):
+        """Run directive."""
+        try:
+            language = self.arguments[0]
+        except IndexError:
+            language = ''
+        code = '\n'.join(self.content)
+        literal = docutils.nodes.literal_block(code, code)
+        literal['classes'].append('code-block')
+        literal['language'] = language
+        return [literal]
+
+
+def register_code_directive():
+    """Register code directive."""
+    if not SPHINX_INSTALLED:
+        docutils.parsers.rst.directives.register_directive('code',
+                                                           CodeBlockDirective)
+        docutils.parsers.rst.directives.register_directive('code-block',
+                                                           CodeBlockDirective)
+        docutils.parsers.rst.directives.register_directive('sourcecode',
+                                                           CodeBlockDirective)
+
+
+def strip_byte_order_mark(text):
+    """Return text with byte order mark (BOM) removed."""
+    try:
+        return text.encode('utf-8').decode('utf-8-sig')
+    except UnicodeError:
+        return text
+
+
 def check(source,
           filename='<string>',
           report_level=docutils.utils.Reporter.INFO_LEVEL,
@@ -98,6 +151,11 @@
     Each code block is checked asynchronously in a subprocess.
 
     """
+    # Do this at call time rather than import time to avoid unnecessarily
+    # mutating state.
+    register_code_directive()
+    ignore_sphinx()
+
     ignore = ignore or []
 
     try:
@@ -109,6 +167,11 @@
 
     string_io = io.StringIO()
 
+    # This is a hack to avoid false positive from docutils (#23). docutils
+    # mistakes BOMs for actual visible letters. This results in the "underline
+    # too short" warning firing.
+    source = strip_byte_order_mark(source)
+
     try:
         docutils.core.publish_string(
             source, writer=writer,
@@ -185,7 +248,7 @@
 
     ignore_from_config(os.path.dirname(os.path.realpath(filename)))
     ignore_directives_and_roles(args.ignore_directives, args.ignore_roles)
-    ignore_sphinx()
+
     for substitution in args.ignore_substitutions:
         contents = contents.replace('|{}|'.format(substitution), 'None')
 
@@ -222,6 +285,21 @@
         yield (int(line_number), message)
 
 
+def check_xml(code):
+    """Yield errors."""
+    try:
+        ElementTree.fromstring(code)
+    except ElementTree.ParseError as exception:
+        message = '{}'.format(exception)
+        line_number = 0
+
+        found = re.search(r': line\s+([0-9]+)[^:]*$', message)
+        if found:
+            line_number = int(found.group(1))
+
+        yield (int(line_number), message)
+
+
 def check_rst(code, ignore):
     """Yield errors in nested RST code."""
     filename = '<string>'
@@ -263,16 +341,6 @@
     directives = get_and_split(options, 'ignore_directives')
     roles = get_and_split(options, 'ignore_roles')
 
-    # Deprecated since 1.3.
-    try:
-        roles = split_comma_separated(parser.get('roles', 'ignore'))
-    except (configparser.NoOptionError, configparser.NoSectionError):
-        pass
-    try:
-        directives = split_comma_separated(parser.get('directives', 'ignore'))
-    except (configparser.NoOptionError, configparser.NoSectionError):
-        pass
-
     return (directives, roles)
 
 
@@ -288,21 +356,71 @@
 
 def _get_directives_and_roles_from_sphinx():
     """Return a tuple of Sphinx directive and roles."""
-    sphinx_directives = list(sphinx.domains.std.StandardDomain.directives)
-    sphinx_roles = list(sphinx.domains.std.StandardDomain.roles)
-
-    for domain in [sphinx.domains.c.CDomain,
-                   sphinx.domains.cpp.CPPDomain,
-                   sphinx.domains.javascript.JavaScriptDomain,
-                   sphinx.domains.python.PythonDomain]:
-
-        sphinx_directives += list(domain.directives) + [
-            '{}:{}'.format(domain.name, item)
-            for item in list(domain.directives)]
-
-        sphinx_roles += list(domain.roles) + [
-            '{}:{}'.format(domain.name, item)
-            for item in list(domain.roles)]
+    if SPHINX_INSTALLED:
+        sphinx_directives = list(sphinx.domains.std.StandardDomain.directives)
+        sphinx_roles = list(sphinx.domains.std.StandardDomain.roles)
+
+        for domain in [sphinx.domains.c.CDomain,
+                       sphinx.domains.cpp.CPPDomain,
+                       sphinx.domains.javascript.JavaScriptDomain,
+                       sphinx.domains.python.PythonDomain]:
+
+            sphinx_directives += list(domain.directives) + [
+                '{}:{}'.format(domain.name, item)
+                for item in list(domain.directives)]
+
+            sphinx_roles += list(domain.roles) + [
+                '{}:{}'.format(domain.name, item)
+                for item in list(domain.roles)]
+    else:
+        sphinx_roles = [
+            'abbr',
+            'command',
+            'dfn',
+            'doc',
+            'download',
+            'envvar',
+            'file',
+            'guilabel',
+            'kbd',
+            'keyword',
+            'mailheader',
+            'makevar',
+            'manpage',
+            'menuselection',
+            'mimetype',
+            'newsgroup',
+            'option',
+            'program',
+            'py:func',
+            'ref',
+            'regexp',
+            'samp',
+            'term',
+            'token']
+
+        sphinx_directives = [
+            'autosummary',
+            'currentmodule',
+            'centered',
+            'c:function',
+            'c:type',
+            'include',
+            'deprecated',
+            'envvar',
+            'glossary',
+            'index',
+            'no-code-block',
+            'literalinclude',
+            'hlist',
+            'option',
+            'productionlist',
+            'py:function',
+            'seealso',
+            'toctree',
+            'todo',
+            'versionadded',
+            'versionchanged']
 
     return (sphinx_directives, sphinx_roles)
 
@@ -425,14 +543,15 @@
 
 def c_checker(code, working_directory):
     """Return checker."""
-    return gcc_checker(code, '.c', [os.getenv('CC', 'gcc'), '-std=c99', '-I.'],
+    return gcc_checker(code, '.c',
+                       [os.getenv('CC', 'gcc'), '-std=c99'] + INCLUDE_FLAGS,
                        working_directory=working_directory)
 
 
 def cpp_checker(code, working_directory):
     """Return checker."""
-    return gcc_checker(code, '.cpp', [os.getenv('CXX', 'g++'), '-std=c++0x',
-                                      '-I.'],
+    return gcc_checker(code, '.cpp',
+                       [os.getenv('CXX', 'g++'), '-std=c++0x'] + INCLUDE_FLAGS,
                        working_directory=working_directory)
 
 
@@ -523,11 +642,23 @@
 
         self._add_check(node=node,
                         run=lambda: check_doctest(node.rawsource),
-                        language='doctest')
+                        language='doctest',
+                        is_code_node=False)
 
     def visit_literal_block(self, node):
         """Check syntax of code block."""
+        # For "..code-block:: language"
         language = node.get('language', None)
+        is_code_node = False
+        if not language:
+            # For "..code:: language"
+            is_code_node = True
+            classes = node.get('classes')
+            if 'code' in classes:
+                language = classes[-1]
+            else:
+                return
+
         if language in self.ignore:
             return
 
@@ -542,6 +673,7 @@
             'c': c_checker,
             'cpp': cpp_checker,
             'json': lambda source, _: lambda: check_json(source),
+            'xml': lambda source, _: lambda: check_xml(source),
             'python': lambda source, _: lambda: check_python(source),
             'rst': lambda source, _: lambda: check_rst(source,
                                                        ignore=self.ignore)
@@ -549,11 +681,14 @@
 
         if checker:
             run = checker(node.rawsource, self.working_directory)
-            self._add_check(node=node, run=run, language=language)
+            self._add_check(node=node,
+                            run=run,
+                            language=language,
+                            is_code_node=is_code_node)
 
         raise docutils.nodes.SkipNode
 
-    def _add_check(self, node, run, language):
+    def _add_check(self, node, run, language, is_code_node):
         """Add checker that will be run."""
         def run_check():
             """Yield errors."""
@@ -563,14 +698,16 @@
                     for result in all_results:
                         error_offset = result[0] - 1
 
-                        try:
+                        line_number = getattr(node, 'line', None)
+                        if line_number is not None:
                             yield (
-                                beginning_of_code_block(node, self.contents) +
+                                beginning_of_code_block(
+                                    node=node,
+                                    line_number=line_number,
+                                    full_contents=self.contents,
+                                    is_code_node=is_code_node) +
                                 error_offset,
                                 '({}) {}'.format(language, result[1]))
-                        except TypeError:
-                            # Ignore case where node's line_number is None.
-                            pass
                 else:
                     yield (self.filename, 0, 'unknown error')
         self.checkers.append(run_check)
@@ -582,14 +719,37 @@
         """Ignore."""
 
 
-def beginning_of_code_block(node, full_contents):
+def beginning_of_code_block(node, line_number, full_contents, is_code_node):
     """Return line number of beginning of code block."""
-    line_number = node.line
-    delta = len(node.non_default_attributes())
-    current_line_contents = full_contents.splitlines()[line_number:]
-    blank_lines = next((i for (i, x) in enumerate(current_line_contents) if x),
-                       0)
-    return line_number + delta - 1 + blank_lines - 1 + SPHINX_CODE_BLOCK_DELTA
+    if SPHINX_INSTALLED and not is_code_node:
+        delta = len(node.non_default_attributes())
+        current_line_contents = full_contents.splitlines()[line_number:]
+        blank_lines = next(
+            (i for (i, x) in enumerate(current_line_contents) if x),
+            0)
+        return (
+            line_number +
+            delta - 1 +
+            blank_lines - 1 +
+            SPHINX_CODE_BLOCK_DELTA)
+    else:
+        lines = full_contents.splitlines()
+        code_block_length = len(node.rawsource.splitlines())
+
+        try:
+            # Case where there are no extra spaces.
+            if lines[line_number - 1].strip():
+                return line_number - code_block_length + 1
+        except IndexError:
+            pass
+
+        # The offsets are wrong if the RST text has multiple blank lines after
+        # the code block. This is a workaround.
+        for line_number in range(line_number, 1, -1):
+            if lines[line_number - 2].strip():
+                break
+
+        return line_number - code_block_length
 
 
 class CheckWriter(docutils.writers.Writer):
@@ -625,7 +785,11 @@
     """Return parsed command-line arguments."""
     threshold_choices = docutils.frontend.OptionParser.threshold_choices
 
-    parser = argparse.ArgumentParser(description=__doc__, prog='rstcheck')
+    parser = argparse.ArgumentParser(
+        description=__doc__ + (' Sphinx is enabled.'
+                               if SPHINX_INSTALLED else ''),
+        prog='rstcheck')
+
     parser.add_argument('files', nargs='+', type=decode_filename,
                         help='files to check')
     parser.add_argument('--report', metavar='level',
@@ -649,9 +813,10 @@
                         metavar='roles', default='',
                         help='comma-separated list of roles to ignore')
     parser.add_argument('--debug', action='store_true',
-                        help='show helpful for debugging')
+                        help='show messages helpful for debugging')
     parser.add_argument('--version', action='version',
                         version='%(prog)s ' + __version__)
+
     args = parser.parse_args()
 
     if '-' in args.files and len(args.files) > 1:
@@ -681,42 +846,62 @@
     print(text, file=file)
 
 
[email protected]
+def enable_sphinx_if_possible():
+    """Register Sphinx directives and roles."""
+    if SPHINX_INSTALLED:
+        temporary_directory = tempfile.mkdtemp()
+        try:
+            sphinx.application.Sphinx(srcdir=temporary_directory,
+                                      confdir=None,
+                                      outdir=temporary_directory,
+                                      doctreedir=temporary_directory,
+                                      buildername='dummy',
+                                      status=None)
+            yield
+        finally:
+            shutil.rmtree(temporary_directory)
+    else:
+        yield
+
+
 def main():
     """Return 0 on success."""
     args = parse_args()
 
-    status = 0
-    pool = multiprocessing.Pool(multiprocessing.cpu_count())
-    try:
-        if len(args.files) > 1:
-            # Run in separate process to avoid mutating the global docutils
-            # settings based on the local configuration. It also avoids
-            # mutating the settings when rstcheck is used as a module.
-            results = pool.map(
-                _check_file,
-                [(name, args) for name in args.files])
-        else:
-            # This is for the case where we read from standard in.
-            results = [_check_file((args.files[0], args))]
-
-        for (filename, errors) in results:
-            for error in errors:
-                line_number = error[0]
-                message = error[1]
-
-                if not re.match(r'\([A-Z]+/[0-9]+\)', message):
-                    message = '(ERROR/3) ' + message
-
-                output_message('{}:{}: {}'.format(filename,
-                                                  line_number,
-                                                  message))
-
-                status = 1
-    except IOError as exception:
-        output_message(exception)
-        status = 1
+    with enable_sphinx_if_possible():
+        status = 0
+        pool = multiprocessing.Pool(multiprocessing.cpu_count())
+        try:
+            if len(args.files) > 1:
+                # Run in separate process to avoid mutating the global docutils
+                # settings based on the local configuration. It also avoids
+                # mutating the settings when rstcheck is used as a module.
+                results = pool.map(
+                    _check_file,
+                    [(name, args) for name in args.files])
+            else:
+                # This is for the case where we read from standard in.
+                results = [_check_file((args.files[0], args))]
+
+            for (filename, errors) in results:
+                for error in errors:
+                    line_number = error[0]
+                    message = error[1]
+
+                    if not re.match(r'\([A-Z]+/[0-9]+\)', message):
+                        message = '(ERROR/3) ' + message
+
+                    output_message('{}:{}: {}'.format(filename,
+                                                      line_number,
+                                                      message))
+
+                    status = 1
+        except (IOError, UnicodeError) as exception:
+            output_message(exception)
+            status = 1
 
-    return status
+        return status
 
 
 if __name__ == '__main__':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/setup.cfg new/rstcheck-3.1/setup.cfg
--- old/rstcheck-1.5.1/setup.cfg        2016-03-29 17:13:30.000000000 +0200
+++ new/rstcheck-3.1/setup.cfg  2017-03-08 17:00:34.000000000 +0100
@@ -1,5 +1,5 @@
 [egg_info]
-tag_svn_revision = 0
 tag_build = 
 tag_date = 0
+tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rstcheck-1.5.1/setup.py new/rstcheck-3.1/setup.py
--- old/rstcheck-1.5.1/setup.py 2015-09-18 16:58:09.000000000 +0200
+++ new/rstcheck-3.1/setup.py   2017-01-29 17:31:19.000000000 +0100
@@ -22,7 +22,7 @@
         version=version(),
         url='https://github.com/myint/rstcheck',
         description='Checks syntax of reStructuredText and code blocks nested '
-                    'within it.',
+                    'within it',
         long_description=readme.read(),
         classifiers=[
             'License :: OSI Approved :: MIT License',
@@ -32,10 +32,10 @@
             'Programming Language :: Python :: 3.3',
             'Programming Language :: Python :: 3.4',
             'Programming Language :: Python :: 3.5',
+            'Programming Language :: Python :: 3.6',
             'Topic :: Software Development :: Quality Assurance',
         ],
         keywords='restructuredtext,lint,check,pypi,readme,rst,analyze',
         py_modules=['rstcheck'],
         entry_points={'console_scripts': ['rstcheck = rstcheck:main']},
-        install_requires=['docutils', 'sphinx']
-    )
+        install_requires=['docutils >= 0.7'])


Reply via email to