def from_org(cls: Type[B], node: OrgNode) -> B: annotations: List[Annotation] = [ Annotation.from_org(anode) for anode in node.children ] author: AuthorName = node.get_property("AUTHOR") series: Optional[Series] = node.get_property("SERIES") body: str = node.body.strip() if node.body.strip() else None for p in ["AUTHOR", "SERIES"]: try: del node.properties[p] except KeyError: pass status, heading = super().parse_heading(node) book: B = cls( title=heading, author=author, series=series, creation_date=cls._get_creation_date(annotations), body=body, status=status, properties={ key.lower(): value for key, value in node.properties.items() }, annotations=annotations, ) return book
def get_body_compat(node: OrgNode) -> str: try: return node.get_body(format='raw') except Exception as e: if node.is_root(): # get_body was only added to root in 0.2.0 for x in warn_old_orgparse_once(): # ugh. really crap, but it will at least only warn once... (becaue it caches) raise x return UPDATE_ORGPARSE_WARNING else: raise e
def _parse_node(n: OrgNode) -> Parsed: if n.is_root(): return Parsed(dt=None, heading='') heading = n.get_heading('raw') pp = n.properties or {} createds = pp.get('CREATED', None) if createds is None: # TODO replace with 'match', but need to strip off priority etc first? # see _parse_heading in orgparse m = rgx.search(heading) if m is not None: createds = m.group(0) # could be None # TODO a bit hacky.. heading = heading.replace(createds + ' ', '') if createds is not None: [odt] = OrgDate.list_from_str(createds) dt = odt.start else: dt = None return Parsed(dt=dt, heading=heading)
def _parse_node(n: OrgNode) -> Parsed: if n.is_root(): return Parsed(dt=None, heading='') heading = n.get_heading('raw') pp = n.properties createds = cast(Optional[str], pp.get('CREATED', None)) if createds is None: # TODO replace with 'match', but need to strip off priority etc first? # see _parse_heading in orgparse # todo maybe use n.get_timestamps(inactive=True, point=True)? only concern is that it's searching in the body as well? m = CREATED_RGX.search(heading) if m is not None: createds = m.group(0) # could be None # todo a bit hacky.. heading = heading.replace(createds + ' ', '') if createds is not None: [odt] = OrgDate.list_from_str(createds) dt = odt.start else: dt = None return Parsed(dt=dt, heading=heading)
def iter_org_urls(n: OrgNode) -> Iterator[Res[Url]]: logger = get_logger() # todo not sure if it can fail? but for now, paranoid just in case try: heading = _get_heading(n) except Exception as e: logger.exception(e) yield e else: yield from iter_urls(heading, syntax='org') try: content = n.get_body(format='raw') except Exception as e: logger.exception(e) yield e else: yield from iter_urls(content, syntax='org')
def _get_heading(n: OrgNode): # todo not sure if it's really that useful to distinguish root and non-root... # maybe have a mode that returns uniform entries, and just relies on the convention return '' if n.is_root() else n.get_heading(format='raw')
def _get_body(n: OrgNode): if n.is_root(): return '\n'.join(n._lines) else: return n.get_body(format='raw')
def _get_heading(n: OrgNode): return '' if n.is_root() else n.get_heading( format='raw') # TODO convert links to html?