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(line
)
65 stars
, text
= match
.group(1), match
.group(2)
66 match
= TAGS_PAT
.search(text
)
67 tags
= match
and match
.group(1).strip(':').split(':') or ()
68 return len(stars
), text
, tags
70 def node(text
, children
, tags
):
71 return {'text': text
, 'children': children
, 'tags': tags
}
73 istack
= [[], [], [], [], [], [], [], [], []] # and so on ...
76 for index
, text
in items
:
77 n
, text
, tags
= splititem(text
)
82 istack
[n
].append(node(text
, reverse(istack
[pn
]), tags
))
85 # previous sibling OR child of one of the top nodes
86 istack
[n
].append(node(text
, [], tags
))
89 return reverse(istack
[1])
91 return hier(by_star())
93 def org2json(orgtext
):
94 return dumps(org2py(orgtext
))
97 if __name__
== '__main__':
98 from doctest
import testmod
101 from pprint
import pprint
102 pprint( org2py(open('sample.org').read()) )