1# -*- coding: utf-8 -*- 2# Copyright (C) 2016 Adrien Vergé 3# 4# This program is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17import string 18 19import yaml 20 21from yamllint.linter import LintProblem 22 23 24def spaces_after(token, prev, next, min=-1, max=-1, 25 min_desc=None, max_desc=None): 26 if next is not None and token.end_mark.line == next.start_mark.line: 27 spaces = next.start_mark.pointer - token.end_mark.pointer 28 if max != - 1 and spaces > max: 29 return LintProblem(token.start_mark.line + 1, 30 next.start_mark.column, max_desc) 31 elif min != - 1 and spaces < min: 32 return LintProblem(token.start_mark.line + 1, 33 next.start_mark.column + 1, min_desc) 34 35 36def spaces_before(token, prev, next, min=-1, max=-1, 37 min_desc=None, max_desc=None): 38 if (prev is not None and prev.end_mark.line == token.start_mark.line and 39 # Discard tokens (only scalars?) that end at the start of next line 40 (prev.end_mark.pointer == 0 or 41 prev.end_mark.buffer[prev.end_mark.pointer - 1] != '\n')): 42 spaces = token.start_mark.pointer - prev.end_mark.pointer 43 if max != - 1 and spaces > max: 44 return LintProblem(token.start_mark.line + 1, 45 token.start_mark.column, max_desc) 46 elif min != - 1 and spaces < min: 47 return LintProblem(token.start_mark.line + 1, 48 token.start_mark.column + 1, min_desc) 49 50 51def get_line_indent(token): 52 """Finds the indent of the line the token starts in.""" 53 start = token.start_mark.buffer.rfind('\n', 0, 54 token.start_mark.pointer) + 1 55 content = start 56 while token.start_mark.buffer[content] == ' ': 57 content += 1 58 return content - start 59 60 61def get_real_end_line(token): 62 """Finds the line on which the token really ends. 63 64 With pyyaml, scalar tokens often end on a next line. 65 """ 66 end_line = token.end_mark.line + 1 67 68 if not isinstance(token, yaml.ScalarToken): 69 return end_line 70 71 pos = token.end_mark.pointer - 1 72 while (pos >= token.start_mark.pointer - 1 and 73 token.end_mark.buffer[pos] in string.whitespace): 74 if token.end_mark.buffer[pos] == '\n': 75 end_line -= 1 76 pos -= 1 77 return end_line 78 79 80def is_explicit_key(token): 81 # explicit key: 82 # ? key 83 # : v 84 # or 85 # ? 86 # key 87 # : v 88 return (token.start_mark.pointer < token.end_mark.pointer and 89 token.start_mark.buffer[token.start_mark.pointer] == '?') 90