Emit warning if over dedent has detected on `literalinclude` directive

This commit is contained in:
Takeshi KOMIYA 2017-02-18 01:01:00 +09:00
parent b0acce8f55
commit 0da80cf302
2 changed files with 20 additions and 10 deletions

View File

@ -56,6 +56,8 @@ Features added
:confval:`suppress_warnings`. :confval:`suppress_warnings`.
* #3377: latex: Add support for Docutils 0.13 ``:align:`` option for tables * #3377: latex: Add support for Docutils 0.13 ``:align:`` option for tables
(but does not implement text flow around table). (but does not implement text flow around table).
* Emit warning if over dedent has detected on ``literalinclude`` directive
(refs: #3416)
Bugs fixed Bugs fixed
---------- ----------

View File

@ -17,6 +17,7 @@ from docutils.statemachine import ViewList
from sphinx import addnodes from sphinx import addnodes
from sphinx.locale import _ from sphinx.locale import _
from sphinx.util import logging
from sphinx.util import parselinenos from sphinx.util import parselinenos
from sphinx.util.nodes import set_source_info from sphinx.util.nodes import set_source_info
@ -26,6 +27,8 @@ if False:
from sphinx.application import Sphinx # NOQA from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA from sphinx.config import Config # NOQA
logger = logging.getLogger(__name__)
class Highlight(Directive): class Highlight(Directive):
""" """
@ -54,11 +57,14 @@ class Highlight(Directive):
linenothreshold=linenothreshold)] linenothreshold=linenothreshold)]
def dedent_lines(lines, dedent): def dedent_lines(lines, dedent, location=None):
# type: (List[unicode], int) -> List[unicode] # type: (List[unicode], int, Any) -> List[unicode]
if not dedent: if not dedent:
return lines return lines
if any(s[:dedent].strip() for s in lines):
logger.warning(_('Over dedent has detected'), location=location)
new_lines = [] new_lines = []
for line in lines: for line in lines:
new_line = line[dedent:] new_line = line[dedent:]
@ -124,8 +130,9 @@ class CodeBlock(Directive):
hl_lines = None hl_lines = None
if 'dedent' in self.options: if 'dedent' in self.options:
location = self.state_machine.get_source_and_line(self.lineno)
lines = code.split('\n') lines = code.split('\n')
lines = dedent_lines(lines, self.options['dedent']) lines = dedent_lines(lines, self.options['dedent'], location=location)
code = '\n'.join(lines) code = '\n'.join(lines)
literal = nodes.literal_block(code, code) literal = nodes.literal_block(code, code)
@ -188,8 +195,8 @@ class LiteralIncludeReader(object):
raise ValueError(_('Cannot use both "%s" and "%s" options') % raise ValueError(_('Cannot use both "%s" and "%s" options') %
(option1, option2)) (option1, option2))
def read_file(self, filename): def read_file(self, filename, location=None):
# type: (unicode) -> List[unicode] # type: (unicode, Any) -> List[unicode]
try: try:
with codecs.open(filename, 'r', self.encoding, errors='strict') as f: # type: ignore # NOQA with codecs.open(filename, 'r', self.encoding, errors='strict') as f: # type: ignore # NOQA
text = f.read() # type: unicode text = f.read() # type: unicode
@ -198,7 +205,7 @@ class LiteralIncludeReader(object):
lines = text.splitlines(True) lines = text.splitlines(True)
if 'dedent' in self.options: if 'dedent' in self.options:
return dedent_lines(lines, self.options.get('dedent')) return dedent_lines(lines, self.options.get('dedent'), location=location)
else: else:
return lines return lines
except (IOError, OSError) as exc: except (IOError, OSError) as exc:
@ -208,8 +215,8 @@ class LiteralIncludeReader(object):
'be wrong, try giving an :encoding: option') % 'be wrong, try giving an :encoding: option') %
(self.encoding, filename)) (self.encoding, filename))
def read(self): def read(self, location=None):
# type: () -> Tuple[unicode, int] # type: (Any) -> Tuple[unicode, int]
if 'diff' in self.options: if 'diff' in self.options:
lines = self.show_diff() lines = self.show_diff()
else: else:
@ -219,7 +226,7 @@ class LiteralIncludeReader(object):
self.lines_filter, self.lines_filter,
self.prepend_filter, self.prepend_filter,
self.append_filter] self.append_filter]
lines = self.read_file(self.filename) lines = self.read_file(self.filename, location=location)
for func in filters: for func in filters:
lines = func(lines) lines = func(lines)
@ -386,11 +393,12 @@ class LiteralInclude(Directive):
self.options['diff'] = path self.options['diff'] = path
try: try:
location = self.state_machine.get_source_and_line(self.lineno)
rel_filename, filename = env.relfn2path(self.arguments[0]) rel_filename, filename = env.relfn2path(self.arguments[0])
env.note_dependency(rel_filename) env.note_dependency(rel_filename)
reader = LiteralIncludeReader(filename, self.options, env.config) reader = LiteralIncludeReader(filename, self.options, env.config)
text, lines = reader.read() text, lines = reader.read(location=location)
retnode = nodes.literal_block(text, text, source=filename) retnode = nodes.literal_block(text, text, source=filename)
set_source_info(self, retnode) set_source_info(self, retnode)