Source code for pyorg.io

"""Read (and write) org mode data from JSON and other formats."""

from .ast import OrgNode, NODE_CLASSES
from pyorg.parse import parse_tags
from .agenda import OrgAgendaItem


JSON_OBJ_DATA_TYPE_KEY = '$$data_type'


def _node_from_json(data, **kw):
	type_ = data['type']

	# Parse child nodes first
	props = _mapping_from_json(data['properties'], **kw)
	if kw.get('recurse_contents', True):
		contents = [_from_json(c, **kw) for c in data['contents']]
	else:
		contents = []
	keywords = _mapping_from_json(data.get('keywords', {}), **kw)

	cls = NODE_CLASSES.get(type_, OrgNode)
	node = cls(type_, props=props, contents=contents, keywords=keywords)

	return node


def _from_json(data, **kw):
	if isinstance(data, list):
		return [_from_json(item, **kw) for item in  data]

	if isinstance(data, dict):
		data = dict(data)
		datatype = data.pop(JSON_OBJ_DATA_TYPE_KEY, 'mapping')
		if datatype == 'org-node':
			return _node_from_json(data, **kw)
		if datatype == 'mapping':
			return _mapping_from_json(data, **kw)
		if datatype == 'error':
			print('Parse error:', data['message'])
			return None
		raise ValueError(data)

	if isinstance(data, (type(None), bool, int, float, str)):
		return data

	raise TypeError(type(data))


def _mapping_from_json(data, **kw):
	return {k: _from_json(v, **kw) for k, v in data.items() if k != JSON_OBJ_DATA_TYPE_KEY}


[docs]def org_node_from_json(data): """Parse an org AST node from JSON data. Returns ------- .OrgNode """ return _node_from_json(data)
[docs]def agenda_item_from_json(data): """Parse an agenda item from JSON data. Parameters ---------- data : dict Returns ------- .OrgAgendaItem """ node_json = data.pop('node') headline = _node_from_json(node_json, recurse_contents=False) item = _mapping_from_json(data) attrs = {'headline': headline} attrmap = { 'type': 'type', 'keyword': 'todo', 'headline_path': 'path', 'file': 'file-relative', 'deadline': 'deadline', 'view_priority': 'priority', 'priority': 'priority-letter', 'category': 'category', } for attr, key in attrmap.items(): try: attrs[attr] = item.pop(key) except KeyError: pass # Get rich and plain text from headline node if possible txt = item.pop('txt') if headline is not None: text = headline['title'] attrs['text_plain'] = headline.title else: text = [txt] attrs['text_plain'] = txt # attrs['tags'] = parse_tags(item.pop('tags', None) or '') attrs['tags'] = item.pop('tags') ignore = { 'file', 'done-face', 'help-echo', 'mouse-face', 'org-not-done-regexp', 'org-complex-heading-regexp', 'org-todo-regexp', } for key in ignore: item.pop(key) return OrgAgendaItem(text, **attrs, **item)