0

For a YAML-editor project I need a way to spot elements of the parsed structure in the YAML-text and vice versa.

Imagine a YAML file which represents a list at top level. When moving the text cursor (inside the editor I want to create) I want the list element located by the cursor to be specially handled (e.g. displayed in a special way).

And the other way round, by navigating a somehow visualized structure (e.g. a list view) I want to have the cursor of the editor jump to the according position.

So what I think I need is just a normal YAML parser which - additionally to the parsed data structure - provides me with a tree-like positional mapping between the JSON text and the parsed data structure.

Since I'm aiming at an embedded project (using PyQt with pyqtdeploy) the most appreciated approach would be based on plain Python (or even using only standard libraries).

frans
  • 8,868
  • 11
  • 58
  • 132

1 Answers1

0

Ok, found Parsing YAML, return with line number now. I've improved the provided answers a bit (in order to not mix parsed data and locations in the end product) and came up with this:

import yaml, sys

class SafeLineLoader(yaml.loader.SafeLoader):
    def construct_mapping(self, node, deep=False):
        mapping = super().construct_mapping(node, deep=deep)
        mapping['__line__'] = node.start_mark.line + 1
        return mapping

def parse_with_locations(uri):
    locations = {}
    data = yaml.load(open(uri), Loader=SafeLineLoader)
    for elem in data:
        oid, line = id(elem), elem["__line__"]
        locations[line] = oid
        locations[oid] = line
        del elem["__line__"]        
    return data, locations
    
data, locations = parse_with_locations(sys.argv[1])
for l in data:
    print(f"@{locations[id(l)]}: {l}")

Note: this code intentionally does not work on arbitrary YAML data but on lists only. (can be improved, though)

frans
  • 8,868
  • 11
  • 58
  • 132