2 # parse a org-mode file and convert it to JSON
4 __author__
= "Sridhar Ratnakumar <http://nearfar.org/>"
7 from itertools
import count
9 from simplejson
import dumps
14 >>> print list(rindexed(l))
15 [(2, 9), (1, 7), (0, 5)]
18 range(len(seq
))[::-1],
28 """Parse the given org file text and return the Python data structure
30 >>> j = org2py(open('sample.org').read())
43 lines
= orgtext
.splitlines()
45 return '\n'.join(lines
[i1
:i2
])
48 last_index
= len(lines
)
49 for index
, line
in rindexed(lines
):
50 if line
.startswith("*"):
51 yield [index
, e(index
, last_index
)]
55 STARS_PAT
= re
.compile(r
"^(\**) (.*)", re
.DOTALL
)
56 TAGS_PAT
= re
.compile(r
"^(.*)\s((\w)*(:(\w)*)*:)$")
59 >>> splititem("*** Foo Bar :TAG1:TAG2:")
60 (3, 'Foo Bar', ('TAG1, 'TAG2'))
61 >>> splititem("** write org-mode tutorial")
62 (2, 'write org-mode tutorial')
64 match
= STARS_PAT
.match(s
)
65 stars
, text
= match
.group(1), match
.group(2)
66 match
= TAGS_PAT
.match(s
.splitlines()[0])
67 tags
= match
and match
.group(2).strip(':').split(':') or ()
68 text
= match
and match
.group(1) or text
69 return len(stars
), text
, tags
71 def node(text
, children
, tags
):
72 return {'text': text
, 'children': children
, 'tags': tags
}
74 istack
= [[], [], [], [], [], [], [], [], []] # and so on ...
77 for index
, text
in items
:
78 n
, text
, tags
= splititem(text
)
83 istack
[n
].append(node(text
, reverse(istack
[pn
]), tags
))
86 # previous sibling OR child of one of the top nodes
87 istack
[n
].append(node(text
, [], tags
))
90 return reverse(istack
[1])
92 return hier(by_star())
94 def org2json(orgtext
):
95 return dumps(org2py(orgtext
))
98 if __name__
== '__main__':
99 from doctest
import testmod
102 from pprint
import pprint
103 pprint( org2py(open('sample.org').read()) )