summaryrefslogtreecommitdiff
path: root/util.py
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2016-02-27 10:15:02 +0100
committerAnthon van der Neut <anthon@mnt.org>2016-02-27 10:15:02 +0100
commit2f9cdc98cc0adea615cb2180481c7780eef48f97 (patch)
treeff710ad0913ced7c241f0445e95e6eefeb24ae1b /util.py
parentacc0b296466c5364569b1df8402d2cb95ca01915 (diff)
downloadruamel.yaml-2f9cdc98cc0adea615cb2180481c7780eef48f97.tar.gz
pep8 compliance, util.load_yaml_guess_indent0.11.2
Diffstat (limited to 'util.py')
-rw-r--r--util.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/util.py b/util.py
new file mode 100644
index 0000000..324bdc7
--- /dev/null
+++ b/util.py
@@ -0,0 +1,118 @@
+# coding: utf-8
+
+"""
+some helper functions that might be generally useful
+"""
+
+from __future__ import print_function
+from __future__ import absolute_import
+
+from .compat import text_type, binary_type
+from .main import round_trip_load
+
+
+# originally as comment
+# https://github.com/pre-commit/pre-commit/pull/211#issuecomment-186466605
+# if you use this in your code, I suggest adding a test in your test suite
+# that check this routines output against a known piece of your YAML
+# before upgrades to this code break your round-tripped YAML
+def load_yaml_guess_indent(stream):
+ # load a yaml file guess the indentation, if you use TABs ...
+ if isinstance(stream, text_type):
+ yaml_str = stream
+ elif isinstance(stream, binary_type):
+ yaml_str = stream.decode('utf-8') # most likely, but the Reader checks BOM for this
+ else:
+ yaml_str = stream.read()
+ indent = None # default if not found for some reason
+ prev_line_key_only = None
+ for line in yaml_str.splitlines():
+ rline = line.rstrip()
+ if rline.startswith('- '):
+ idx = 1
+ while line[idx] == ' ': # this will end as we rstripped
+ idx += 1
+ if line[idx] == '#': # comment after -
+ continue
+ indent = idx
+ break
+ if rline.endswith(':'):
+ idx = 0
+ while line[idx] == ' ': # this will end on ':'
+ idx += 1
+ prev_line_key_only = idx
+ continue
+ if prev_line_key_only is not None and rline:
+ idx = 0
+ while line[idx] in ' -': # this will end on ':'
+ idx += 1
+ if idx > prev_line_key_only:
+ indent = idx - prev_line_key_only
+ break
+ prev_line_key_only = None
+ return round_trip_load(yaml_str), indent
+
+
+def configobj_walker(cfg):
+ """
+ walks over a ConfigObj (INI file with comments) generating
+ corresponding YAML output (including comments
+ """
+ from configobj import ConfigObj
+ assert isinstance(cfg, ConfigObj)
+ for c in cfg.initial_comment:
+ if c.strip():
+ yield c
+ for s in _walk_section(cfg):
+ if s.strip():
+ yield s
+ for c in cfg.final_comment:
+ if c.strip():
+ yield c
+
+
+def _walk_section(s, level=0):
+ from configobj import Section
+ assert isinstance(s, Section)
+ indent = u' ' * level
+ for name in s.scalars:
+ for c in s.comments[name]:
+ yield indent + c.strip()
+ x = s[name]
+ if u'\n' in x:
+ i = indent + u' '
+ x = u'|\n' + i + x.strip().replace(u'\n', u'\n' + i)
+ elif ':' in x:
+ x = u"'" + x.replace(u"'", u"''") + u"'"
+ line = u'{0}{1}: {2}'.format(indent, name, x)
+ c = s.inline_comments[name]
+ if c:
+ line += u' ' + c
+ yield line
+ for name in s.sections:
+ for c in s.comments[name]:
+ yield indent + c.strip()
+ line = u'{0}{1}:'.format(indent, name)
+ c = s.inline_comments[name]
+ if c:
+ line += u' ' + c
+ yield line
+ for val in _walk_section(s[name], level=level+1):
+ yield val
+
+# def config_obj_2_rt_yaml(cfg):
+# from .comments import CommentedMap, CommentedSeq
+# from configobj import ConfigObj
+# assert isinstance(cfg, ConfigObj)
+# #for c in cfg.initial_comment:
+# # if c.strip():
+# # pass
+# cm = CommentedMap()
+# for name in s.sections:
+# cm[name] = d = CommentedMap()
+#
+#
+# #for c in cfg.final_comment:
+# # if c.strip():
+# # yield c
+# return cm