# Python script to convert hierarchical JSON to LaTeX itemize

I have the following JSON:

{
"items": [
{
"item": "abc",
},
{
"item": "def",
},
{
"item": "ghi",
"status": "done",
"items": [
{
"item": "ABC",
},
{
"item": "DEF",
},
{
"item": "GHI",
"status": "done"
}
]
}
]
}


which I would like to convert to:

\begin{itemize}
\item ghi\hfill{}done
\begin{itemize}
\item GHI\hfill{}done
\end{itemize}
\end{itemize}


The items can be nested arbitrarily deep. I have the following Python code:

import json
import os

TAB = '  '
BEGIN = '\\begin{itemize}'
ITEM = '\\item {0}\\hfill{{}}{1}'
END = '\\end{itemize}'

def main(path):
with open(os.path.join(path, 'test.json')) as data_file:
print('\n'.join(convert(data)))

def convert(data):
stack = [data['items'].__iter__()]
yield (TAB * (len(stack) - 1)) + BEGIN
while len(stack) > 0:
iterator = stack[len(stack) - 1]
try:
current = iterator.next()
yield (TAB * (len(stack) - 1)) + ITEM.format(current['item'], current['status'])
try:
stack.append(current['items'].__iter__())
yield (TAB * (len(stack) - 1)) + BEGIN
except KeyError:
pass
except StopIteration:
yield (TAB * (len(stack) - 1)) + END
stack.pop()


I am new to Python and am looking for suggestions for the code to be more idiomatic Python.

Unless you specifically want a tab of 2 spaces in the resulting LaTeX, you can use '\t' to get the actual tab character.

TAB = '\t'


When working with strings with one or more backslashes, you can declare them as 'raw' strings by prefixing them with an r, which allows you to write backslash characters without having to escape them.

BEGIN = r'\begin{itemize}'
ITEM = r'\item {0}\hfill{{}}{1}'
END = r'\end{itemize}'


You can use the magic method iter() to get iterators, for example:

stack = [iter(data['items'])]


or

stack.append(iter(current['items']))


This is more idiomatic than calling the __iter__() method directly. In addition, there is a next() magic method as well which you can use to get the next item from an iterator.

current = next(iterator)


If you are using Python 3.4 or higher, I'd recommend checking out the pathlib module for manipulating file paths over os.path, but in this case using os.path does the job and is probably sufficient.