Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Change Log
----------

1.0.5

- Support xmind zen file type.

1.0.4

- Support parse label feature.
Expand Down
44 changes: 41 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![PyPI](https://img.shields.io/pypi/v/xmindparser.svg)](https://pypi.org/project/xmindparser/)

Parse xmind file to programmable data type (e.g. json, xml). Python 3.x required.
Parse xmind file to programmable data type (e.g. json, xml). Python 3.x required. Now we support XmindZen file type as well.

See also: [xmind2testlink](https://github.com/tobyqin/xmind2testlink) / [中文文档](https://betacat.online/posts/2018-07-01/parse-xmind-to-programmable-data-type/)

Expand Down Expand Up @@ -52,7 +52,7 @@ print(d)

```

## Limitations
## Limitations (for XmindPro, legacy version)

Please note, following xmind features will not be supported or partially supported.

Expand All @@ -66,10 +66,48 @@ Please note, following xmind features will not be supported or partially support
- Will not parse image object, only name it as `[Image]`
- Rich text format in notes will be parsed as plain text.

# XmindZen Updates

XmindParser will auto detect xmind file created by XmindZen, so you just pass in the file, use it as usual.

```python
from xmindparser import xmind_to_dict

d = xmind_to_dict('/path/to/your/xmind_zen_file')
print(d)
```

Please note, there are a few differences between xmind pro and xmind zen.

- Remove comments, so I will not parse comments.
- Add sticker, but I will not parse it.
- Add callout, this is supported.

Since XmindZen has upgraded the file manifest as json, you can read the built-in json by code like this:

```python
import json

def open_xmind(file_path):
name = "content.json"
with ZipFile(file_path) as xmind:
if name in xmind.namelist():
content = xmind.open(name).read().decode('utf-8')
return json.loads(content)

raise AssertionError("Not a xmind zen file type!")

# xmindparser also provides a shortcut
from xmindparser import get_xmind_zen_builtin_json

content_json = get_xmind_zen_builtin_json(xmind_zen_file)
```

## Examples

![Xmind Example](doc/xmind.png)
[(Download this file)](tests/test.xmind)
[(Download xmind pro file)](tests/xmind_pro.xmind)
[(Download xmind zen file)](tests/xmind_zen.xmind)

- xmind to [json example](doc/example.json)
- xmind to [xml example](doc/example.xml)
Expand Down
117 changes: 117 additions & 0 deletions doc/example_zen.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
[
{
"structure": "org.xmind.ui.map.unbalanced",
"topic": {
"topics": [
{
"makers": [
"priority-1"
],
"topics": [
{
"note": "note info\nnew line of note",
"title": "note topic"
},
{
"topics": [
{
"note": "hello world",
"title": "formatted note"
}
],
"labels": [
"great"
],
"title": "label topic"
},
{
"link": "http://www.link.com",
"title": "link topic"
},
{
"title": "callout topic",
"callout": [
"Callout"
]
},
{
"makers": [
"priority-2",
"smiley-smile",
"task-oct",
"flag-orange"
],
"title": "makers topic"
},
{
"title": "sticker topic"
},
{
"title": "image topic"
},
{
"topics": [
{
"link": "xap:resources/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.txt",
"title": "test.txt"
}
],
"title": "attachment topic"
}
],
"title": "topic 1"
},
{
"makers": [
"priority-2"
],
"topics": [
{
"title": "123"
},
{
"topics": [
{
"title": "topic after empty"
}
],
"title": ""
},
{
"title": "\u4e2d\u6587"
},
{
"topics": [
{
"title": "topic with special chars"
}
],
"title": "<>{}*&^^&*^%@!"
},
{
"title": "formatted topic"
}
],
"title": "topic 2"
}
],
"title": "Central Topic"
},
"title": "Map 1"
},
{
"structure": "org.xmind.ui.map.unbalanced",
"topic": {
"topics": [
{
"title": "Main Topic 1"
},
{
"title": "Main Topic 2"
}
],
"title": "another sheet"
},
"title": "Map 2"
}
]
142 changes: 142 additions & 0 deletions doc/example_zen_with_id.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
[
{
"topic": {
"topics": [
{
"makers": [
"priority-1"
],
"topics": [
{
"note": "note info\nnew line of note",
"title": "note topic",
"id": "62406618-32b1-486d-82b4-57f319fa633a"
},
{
"topics": [
{
"note": "hello world",
"title": "formatted note",
"id": "f5a46c76-3dc0-48a4-b93f-59a8ecfc3340"
}
],
"title": "label topic",
"id": "68405d18-e77d-4fb4-9db5-8bb003baa758",
"labels": [
"great"
]
},
{
"link": "http://www.link.com",
"title": "link topic",
"id": "b588cc21-4a33-4108-8a3d-4a066714581a"
},
{
"callout": [
"Callout"
],
"title": "callout topic",
"id": "1a14cbd3-9ead-4867-af1e-9781d2fe8927"
},
{
"makers": [
"priority-2",
"smiley-smile",
"task-oct",
"flag-orange"
],
"title": "makers topic",
"id": "44d2dea9-9d68-4237-b5c0-1d02632381d1"
},
{
"title": "sticker topic",
"id": "6657af1e-4770-4ff4-9a09-66f546e4c720"
},
{
"title": "image topic",
"id": "a5ffd21b-2fda-4dd4-8a64-6490a9aaa46d"
},
{
"topics": [
{
"link": "xap:resources/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.txt",
"title": "test.txt",
"id": "2ba4c9fa-5bb4-4715-985f-d8316e1c6b55"
}
],
"title": "attachment topic",
"id": "2cac3535-1d74-44d9-9621-04708a134ac5"
}
],
"title": "topic 1",
"id": "b58888b5ceebbf0e68dada0656"
},
{
"makers": [
"priority-2"
],
"topics": [
{
"title": "123",
"id": "68bb7a52-1e41-4a29-b9b8-204b3d17ee5f"
},
{
"topics": [
{
"title": "topic after empty",
"id": "357e5088-f207-41c9-b920-01f4d955dcaa"
}
],
"title": "",
"id": "810acef9-36a1-4580-bec0-7cce95661838"
},
{
"title": "\u4e2d\u6587",
"id": "fae3efe0-dbcc-46c9-975c-d60ca8fc6455"
},
{
"topics": [
{
"title": "topic with special chars",
"id": "f8942451-183b-4dc6-9816-bc4b9baa7686"
}
],
"title": "<>{}*&^^&*^%@!",
"id": "6b9e69af-6e90-456b-b2d7-1fe564ec97ed"
},
{
"title": "formatted topic",
"id": "f0d31da3-59aa-4c68-b909-ab44a6dc76d7"
}
],
"title": "topic 2",
"id": "193b56735e689ae86a01d91513"
}
],
"title": "Central Topic",
"id": "b9aa22deba98b3b20c7ac8aca2"
},
"structure": "org.xmind.ui.map.unbalanced",
"title": "Map 1",
"id": "1fb9723a328b06763d296b8fee"
},
{
"topic": {
"topics": [
{
"title": "Main Topic 1",
"id": "da88f9a5ad9a201fb6618a0d65"
},
{
"title": "Main Topic 2",
"id": "33284f5d0e89964530c77a7299"
}
],
"title": "another sheet",
"id": "495938ff229b6b4f6ef178ea3f"
},
"structure": "org.xmind.ui.map.unbalanced",
"title": "Map 2",
"id": "f3e8391738b81b4beac919ce7c"
}
]
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"Topic :: Utilities",
"Operating System :: Microsoft :: Windows",
"Operating System :: MacOS :: MacOS X"] + [
("Programming Language :: Python :: %s" % x) for x in "3.4 3.5 3.6".split()]
("Programming Language :: Python :: %s" % x) for x in "3.4 3.5 3.6 3.7 3.8".split()]


def command_line():
Expand All @@ -35,11 +35,11 @@ def command_line():
def main():
setup(
name="xmindparser",
description="Convert xmind to programmable data types.",
description="Convert xmind to programmable data types, support xmind pro and xmind zen file types.",
keywords="xmind parser converter json xml",
long_description=long_description,
classifiers=classifiers,
version="1.0.4",
version="1.0.5",
author="Toby Qin",
author_email="toby.qin@live.com",
url="https://github.com/tobyqin/xmindparser",
Expand Down
Loading