# Import README.rst using cog # [[[cog # from cog import out # out('"""\n{0}\n"""'.format(open('../README.rst').read())) # ]]] """ =========================================================== orgparse - Python module for reading Emacs org-mode files =========================================================== * `Documentation (Read the Docs) `_ * `Repository (at GitHub) `_ * `PyPI `_ Install ------- pip install orgparse Usage ----- There are pretty extensive doctests if you're interested in some specific method. Otherwise here are some example snippets: Load org node ^^^^^^^^^^^^^ :: from orgparse import load, loads load('PATH/TO/FILE.org') load(file_like_object) loads(''' * This is org-mode contents You can load org object from string. ** Second header ''') Traverse org tree ^^^^^^^^^^^^^^^^^ >>> root = loads(''' ... * Heading 1 ... ** Heading 2 ... *** Heading 3 ... ''') >>> for node in root[1:]: # [1:] for skipping root itself ... print(node) * Heading 1 ** Heading 2 *** Heading 3 >>> h1 = root.children[0] >>> h2 = h1.children[0] >>> h3 = h2.children[0] >>> print(h1) * Heading 1 >>> print(h2) ** Heading 2 >>> print(h3) *** Heading 3 >>> print(h2.get_parent()) * Heading 1 >>> print(h3.get_parent(max_level=1)) * Heading 1 Accessing node attributes ^^^^^^^^^^^^^^^^^^^^^^^^^ >>> root = loads(''' ... * DONE Heading :TAG: ... CLOSED: [2012-02-26 Sun 21:15] SCHEDULED: <2012-02-26 Sun> ... CLOCK: [2012-02-26 Sun 21:10]--[2012-02-26 Sun 21:15] => 0:05 ... :PROPERTIES: ... :Effort: 1:00 ... :OtherProperty: some text ... :END: ... Body texts... ... ''') >>> node = root.children[0] >>> node.heading 'Heading' >>> node.scheduled OrgDateScheduled((2012, 2, 26)) >>> node.closed OrgDateClosed((2012, 2, 26, 21, 15, 0)) >>> node.clock [OrgDateClock((2012, 2, 26, 21, 10, 0), (2012, 2, 26, 21, 15, 0))] >>> bool(node.deadline) # it is not specified False >>> node.tags == set(['TAG']) True >>> node.get_property('Effort') 60 >>> node.get_property('UndefinedProperty') # returns None >>> node.get_property('OtherProperty') 'some text' >>> node.body ' Body texts...' """ # [[[end]]] from io import IOBase from pathlib import Path from typing import Iterable, Union, Optional, TextIO from .node import parse_lines, OrgEnv, OrgNode # todo basenode?? __all__ = ["load", "loads", "loadi"] def load(path: Union[str, Path, TextIO], env: Optional[OrgEnv] = None) -> OrgNode: """ Load org-mode document from a file. :type path: str or file-like :arg path: Path to org file or file-like object of an org document. :rtype: :class:`orgparse.node.OrgRootNode` """ # Make sure it is a Path object. if isinstance(path, str): path = Path(path) # if it is a Path if isinstance(path, Path): # open that Path with path.open('r', encoding='utf8') as orgfile: # try again loading return load(orgfile, env) # We assume it is a file-like object (e.g. io.StringIO) all_lines = (line.rstrip('\n') for line in path) # get the filename filename = path.name if hasattr(path, 'name') else '' return loadi(all_lines, filename=filename, env=env) def loads(string: str, filename: str='', env: Optional[OrgEnv]=None) -> OrgNode: """ Load org-mode document from a string. :rtype: :class:`orgparse.node.OrgRootNode` """ return loadi(string.splitlines(), filename=filename, env=env) def loadi(lines: Iterable[str], filename: str='', env: Optional[OrgEnv]=None) -> OrgNode: """ Load org-mode document from an iterative object. :rtype: :class:`orgparse.node.OrgRootNode` """ return parse_lines(lines, filename=filename, env=env)