Make packing and unpacking item data consistent

This commit is contained in:
Veronica Berglyd Olsen
2022-11-03 17:30:54 +01:00
parent da4f4b0801
commit 3eee8442a7
9 changed files with 2650 additions and 1873 deletions
+23 -18
View File
@@ -187,29 +187,34 @@ class NWItem:
def unpack(self, data):
"""Set the values from a data dictionary.
"""
if "handle" in data:
self.setHandle(data["handle"])
item = data.get("itemAttr", {})
meta = data.get("metaAttr", {})
name = data.get("nameAttr", {})
if "handle" in item:
self.setHandle(item["handle"])
else:
logger.error("Item does not have a handle")
return False
self.setName(data.get("label", ""))
self.setParent(data.get("parent", None))
self.setRoot(data.get("root", None))
self.setOrder(data.get("order", 0))
self.setType(data.get("type", nwItemType.NO_TYPE))
self.setClass(data.get("class", nwItemClass.NO_CLASS))
self.setLayout(data.get("layout", nwItemLayout.NO_LAYOUT))
self.setName(data.get("name", ""))
self.setParent(item.get("parent", None))
self.setRoot(item.get("root", None))
self.setOrder(item.get("order", 0))
self.setType(item.get("type", nwItemType.NO_TYPE))
self.setClass(item.get("class", nwItemClass.NO_CLASS))
self.setExpanded(meta.get("expanded", False))
self.setStatus(name.get("status", None))
self.setImport(name.get("import", None))
self.setExpanded(data.get("expanded", False))
self.setStatus(data.get("status", None))
self.setImport(data.get("import", None))
self.setMainHeading(data.get("heading", "H0"))
self.setCharCount(data.get("charCount", 0))
self.setWordCount(data.get("wordCount", 0))
self.setParaCount(data.get("paraCount", 0))
self.setCursorPos(data.get("cursorPos", 0))
self.setActive(data.get("active", True))
if self._type == nwItemType.FILE:
self.setLayout(item.get("layout", nwItemLayout.NO_LAYOUT))
self.setMainHeading(meta.get("heading", "H0"))
self.setCharCount(meta.get("charCount", 0))
self.setWordCount(meta.get("wordCount", 0))
self.setParaCount(meta.get("paraCount", 0))
self.setCursorPos(meta.get("cursorPos", 0))
self.setActive(name.get("active", True))
# Make some checks to ensure consistency
if self._type == nwItemType.ROOT:
+60 -42
View File
@@ -68,24 +68,24 @@ class ProjectXMLReader:
"""The main project XML file reader class. All data is read into a
NWProjectData instance, which must be provided.
Version Change History
======================
File Format Version Change History
==================================
1.0 Original file format.
1.1 Changes the way documents are structured in the project folder
from data_X, where X is the first hex value of the handle, to a
single content folder. Introduced in version 0.7.
1.2 Changes the way autoReplace entries are stored. The 1.1 parser
will lose the autoReplace settings if allowed to read the file.
Introduced in version 0.10.
1.2 Changes the way autoReplace entries are stored. Introduced in
version 0.10.
1.3 Reduces the number of layouts to only two. One for novel
documents and one for project notes. Introduced in version 1.5.
1.4 Introduces a more compact format for storing items. All settings
aside from name are now attributes. This format also changes the
way satus and importance labels are stored and handled.
way satus and importance labels, last used handles, and title
formats are stored. They are now all stored as key/value sets.
Introduced in version 2.0.
"""
@@ -158,7 +158,7 @@ class ProjectXMLReader:
except Exception as exc:
# Trying to open backup file instead
logger.error("Failed to parse project xml", exc_info=exc)
logger.error("Failed to parse project XML", exc_info=exc)
self._state = XMLReadState.CANNOT_PARSE
backFile = self._path[:-3]+"bak"
@@ -168,7 +168,7 @@ class ProjectXMLReader:
self._state = XMLReadState.PARSED_BACKUP
logger.info("Backup project file parsed")
except Exception as exc:
logger.error("Failed to parse backup project xml", exc_info=exc)
logger.error("Failed to parse backup project XML", exc_info=exc)
self._state = XMLReadState.CANNOT_PARSE
return False
else:
@@ -205,7 +205,7 @@ class ProjectXMLReader:
else:
self._parseProjectContentLegacy(xSection, projContent, projData)
else:
logger.warning("Ignored <root/%s> in xml", xSection.tag)
logger.warning("Ignored <root/%s> in XML", xSection.tag)
if self._version == 0x0104:
self._state = XMLReadState.PARSED_OK
@@ -238,7 +238,7 @@ class ProjectXMLReader:
elif xItem.tag == "editTime":
projData.setEditTime(xItem.text)
else:
logger.warning("Ignored <root/project/%s> in xml", xItem.tag)
logger.warning("Ignored <root/project/%s> in XML", xItem.tag)
return
@@ -277,7 +277,7 @@ class ProjectXMLReader:
else: # Pre 1.4 format
projData.setTitleFormat(self._parseDictTagText(xItem))
else:
logger.warning("Ignored <root/settings/%s> in xml", xItem.tag)
logger.warning("Ignored <root/settings/%s> in XML", xItem.tag)
return
@@ -289,6 +289,10 @@ class ProjectXMLReader:
for xItem in xSection:
if xItem.tag == "item":
item = {}
meta = {}
name = {}
itemName = ""
item["handle"] = checkStringNone(xItem.attrib.get("handle"), None)
item["parent"] = checkStringNone(xItem.attrib.get("parent"), None)
item["root"] = checkStringNone(xItem.attrib.get("root"), None)
@@ -298,28 +302,33 @@ class ProjectXMLReader:
item["layout"] = checkString(xItem.attrib.get("layout"), "NO_LAYOUT")
for xVal in xItem:
if xVal.tag == "meta":
item["expanded"] = checkBool(xVal.attrib.get("expanded"), False)
item["heading"] = checkString(xVal.attrib.get("heading"), "H0")
item["charCount"] = checkInt(xVal.attrib.get("charCount"), 0)
item["wordCount"] = checkInt(xVal.attrib.get("wordCount"), 0)
item["paraCount"] = checkInt(xVal.attrib.get("paraCount"), 0)
item["cursorPos"] = checkInt(xVal.attrib.get("cursorPos"), 0)
meta["expanded"] = checkBool(xVal.attrib.get("expanded"), False)
meta["heading"] = checkString(xVal.attrib.get("heading"), "H0")
meta["charCount"] = checkInt(xVal.attrib.get("charCount"), 0)
meta["wordCount"] = checkInt(xVal.attrib.get("wordCount"), 0)
meta["paraCount"] = checkInt(xVal.attrib.get("paraCount"), 0)
meta["cursorPos"] = checkInt(xVal.attrib.get("cursorPos"), 0)
elif xVal.tag == "name":
item["label"] = simplified(checkString(xVal.text, ""))
item["status"] = checkStringNone(xVal.attrib.get("status"), None)
item["import"] = checkStringNone(xVal.attrib.get("import"), None)
item["active"] = checkBool(xVal.attrib.get("active"), False)
itemName = simplified(checkString(xVal.text, ""))
name["status"] = checkStringNone(xVal.attrib.get("status"), None)
name["import"] = checkStringNone(xVal.attrib.get("import"), None)
name["active"] = checkBool(xVal.attrib.get("active"), False)
# ToDo: Remove before 2.0 release. Only needed for 2.0 pre-releases.
if "exported" in xVal.attrib:
item["active"] = checkBool(xVal.attrib.get("exported"), False)
name["active"] = checkBool(xVal.attrib.get("exported"), False)
else:
logger.warning("Ignored <root/content/item/%s> in xml", xVal.tag)
logger.warning("Ignored <root/content/item/%s> in XML", xVal.tag)
projContent.append(item)
projContent.append({
"name": itemName,
"itemAttr": item,
"metaAttr": meta,
"nameAttr": name,
})
else:
logger.warning("Ignored item <root/content/%s> in xml", xItem.tag)
logger.warning("Ignored item <root/content/%s> in XML", xItem.tag)
return
@@ -334,17 +343,21 @@ class ProjectXMLReader:
for xItem in xSection:
item = {}
meta = {}
name = {}
itemName = ""
if xItem.tag == "item":
item["handle"] = checkStringNone(xItem.attrib.get("handle", None), None)
item["parent"] = checkStringNone(xItem.attrib.get("parent", None), None)
item["root"] = None # Value was added in 1.4
item["order"] = checkInt(xItem.attrib.get("order", 0), 0)
item["heading"] = "H0" # Value was added in 1.4
meta["heading"] = "H0" # Value was added in 1.4
tmpStatus = ""
for xVal in xItem:
if xVal.tag == "name":
item["label"] = simplified(checkString(xVal.text, ""))
itemName = simplified(checkString(xVal.text, ""))
elif xVal.tag == "status":
tmpStatus = checkStringNone(xVal.text, None)
elif xVal.tag == "type":
@@ -354,25 +367,25 @@ class ProjectXMLReader:
elif xVal.tag == "layout":
item["layout"] = checkString(xVal.text, "")
elif xVal.tag == "expanded":
item["expanded"] = checkBool(xVal.text, False)
meta["expanded"] = checkBool(xVal.text, False)
elif xVal.tag == "exported": # Renamed to active in 1.4
item["active"] = checkBool(xVal.text, False)
name["active"] = checkBool(xVal.text, False)
elif xVal.tag == "charCount":
item["charCount"] = checkInt(xVal.text, 0)
meta["charCount"] = checkInt(xVal.text, 0)
elif xVal.tag == "wordCount":
item["wordCount"] = checkInt(xVal.text, 0)
meta["wordCount"] = checkInt(xVal.text, 0)
elif xVal.tag == "paraCount":
item["paraCount"] = checkInt(xVal.text, 0)
meta["paraCount"] = checkInt(xVal.text, 0)
elif xVal.tag == "cursorPos":
item["cursorPos"] = checkInt(xVal.text, 0)
meta["cursorPos"] = checkInt(xVal.text, 0)
else:
logger.warning("Ignored <root/content/item/%s> in xml", xVal.tag)
logger.warning("Ignored <root/content/item/%s> in XML", xVal.tag)
# Status was split into separate status/import with a key in 1.4
if item.get("class", "") in ("NOVEL", "ARCHIVE"):
item["status"] = statusMap.get(tmpStatus, None)
name["status"] = statusMap.get(tmpStatus, None)
else:
item["import"] = importMap.get(tmpStatus, None)
name["import"] = importMap.get(tmpStatus, None)
# A number of layouts were removed in 1.3
if item.get("layout", "") in (
@@ -384,10 +397,15 @@ class ProjectXMLReader:
if item.get("type", "") == "TRASH":
item["type"] = "ROOT"
projContent.append(item)
projContent.append({
"name": itemName,
"itemAttr": item,
"metaAttr": meta,
"nameAttr": name,
})
else:
logger.warning("Ignored <root/content/%s> in xml", xItem.tag)
logger.warning("Ignored <root/content/%s> in XML", xItem.tag)
return
@@ -495,7 +513,7 @@ class ProjectXMLWriter:
xName = etree.SubElement(xItem, "name", attrib=item.get("nameAttr", {}))
xName.text = item["name"]
# Write the xml tree to file
# Write the XML tree to file
saveFile = os.path.join(self._path, nwFiles.PROJ_FILE)
tempFile = os.path.join(self._path, nwFiles.PROJ_FILE+"~")
backFile = os.path.join(self._path, nwFiles.PROJ_FILE[:-3]+"bak")
@@ -530,14 +548,14 @@ class ProjectXMLWriter:
##
def _packSingleValue(self, xParent, name, value, attrib=None):
"""Pack a single value into an xml element.
"""Pack a single value into an XML element.
"""
xItem = etree.SubElement(xParent, name, attrib=attrib)
xItem.text = str(value) or ""
return
def _packListValue(self, xParent, name, data):
"""Pack a list of values into an xml element.
"""Pack a list of values into an XML element.
"""
for value in data:
xItem = etree.SubElement(xParent, name)
@@ -545,7 +563,7 @@ class ProjectXMLWriter:
return
def _packDictKeyValue(self, xParent, name, data):
"""Pack the entries of a dictionary into an xml element.
"""Pack the entries of a dictionary into an XML element.
"""
xItem = etree.SubElement(xParent, name)
for key, value in data.items():
File diff suppressed because it is too large Load Diff
+449 -317
View File
@@ -1,362 +1,494 @@
[
{
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"heading": "H0",
"label": "Novel",
"type": "ROOT",
"class": "NOVEL",
"expanded": true,
"status": "s000002"
"name": "Novel",
"itemAttr": {
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"type": "ROOT",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000002"
}
},
{
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"heading": "H0",
"label": "Title Page",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 72,
"wordCount": 15,
"paraCount": 2,
"cursorPos": 78,
"status": "s000002"
"name": "Title Page",
"itemAttr": {
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 72,
"wordCount": 15,
"paraCount": 2,
"cursorPos": 78
},
"nameAttr": {
"active": true,
"status": "s000002"
}
},
{
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"heading": "H0",
"label": "Page",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 208,
"wordCount": 40,
"paraCount": 2,
"cursorPos": 213,
"status": "s000000"
"name": "Page",
"itemAttr": {
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 208,
"wordCount": 40,
"paraCount": 2,
"cursorPos": 213
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"heading": "H0",
"label": "Part One",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 23,
"wordCount": 5,
"paraCount": 1,
"cursorPos": 0,
"status": "s000000"
"name": "Part One",
"itemAttr": {
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 23,
"wordCount": 5,
"paraCount": 1,
"cursorPos": 0
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"heading": "H0",
"label": "A Folder",
"type": "FOLDER",
"class": "NOVEL",
"expanded": true,
"status": "s000003"
"name": "A Folder",
"itemAttr": {
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"type": "FOLDER",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000003"
}
},
{
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Chapter One",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 12,
"wordCount": 3,
"paraCount": 0,
"cursorPos": 215,
"status": "s000001"
"name": "Chapter One",
"itemAttr": {
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 12,
"wordCount": 3,
"paraCount": 0,
"cursorPos": 215
},
"nameAttr": {
"active": true,
"status": "s000001"
}
},
{
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"heading": "H0",
"label": "Making a Scene",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 1199,
"wordCount": 216,
"paraCount": 7,
"cursorPos": 527,
"status": "s000003"
"name": "Making a Scene",
"itemAttr": {
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 1199,
"wordCount": 216,
"paraCount": 7,
"cursorPos": 527
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"heading": "H0",
"label": "Another Scene",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 551,
"status": "s000003"
"name": "Another Scene",
"itemAttr": {
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 551
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"heading": "H0",
"label": "Interlude",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 633,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 1238,
"status": "s000006"
"name": "Interlude",
"itemAttr": {
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 633,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 1238
},
"nameAttr": {
"active": true,
"status": "s000006"
}
},
{
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"heading": "H0",
"label": "A Note on Structure",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": false,
"layout": "NOTE",
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1721,
"status": "s000004"
"name": "A Note on Structure",
"itemAttr": {
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"type": "FILE",
"class": "NOVEL",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1721
},
"nameAttr": {
"active": false,
"status": "s000004"
}
},
{
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"heading": "H0",
"label": "Chapter Two",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343,
"status": "s000003"
"name": "Chapter Two",
"itemAttr": {
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"heading": "H0",
"label": "We Found John!",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224,
"status": "s000003"
"name": "We Found John!",
"itemAttr": {
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"heading": "H0",
"label": "Characters",
"type": "ROOT",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Characters",
"itemAttr": {
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"type": "ROOT",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"heading": "H0",
"label": "Main Characters",
"type": "FOLDER",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Main Characters",
"itemAttr": {
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"type": "FOLDER",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"heading": "H0",
"label": "John Smith",
"type": "FILE",
"class": "CHARACTER",
"expanded": false,
"active": true,
"layout": "NOTE",
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24,
"import": "i000008"
"name": "John Smith",
"itemAttr": {
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"heading": "H0",
"label": "Jane Smith",
"type": "FILE",
"class": "CHARACTER",
"expanded": false,
"active": true,
"layout": "NOTE",
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25,
"import": "i000009"
"name": "Jane Smith",
"itemAttr": {
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"heading": "H0",
"label": "Locations",
"type": "ROOT",
"class": "WORLD",
"expanded": true,
"import": null
"name": "Locations",
"itemAttr": {
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"type": "ROOT",
"class": "WORLD"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"heading": "H0",
"label": "Earth",
"type": "FILE",
"class": "WORLD",
"expanded": false,
"active": true,
"layout": "NOTE",
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20,
"import": "i00000a"
"name": "Earth",
"itemAttr": {
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20
},
"nameAttr": {
"active": true,
"import": "i00000a"
}
},
{
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"heading": "H0",
"label": "Space",
"type": "FILE",
"class": "WORLD",
"expanded": false,
"active": true,
"layout": "NOTE",
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133,
"import": "i000008"
"name": "Space",
"itemAttr": {
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"heading": "H0",
"label": "Mars",
"type": "FILE",
"class": "WORLD",
"expanded": false,
"active": true,
"layout": "NOTE",
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45,
"import": "i000009"
"name": "Mars",
"itemAttr": {
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 3,
"heading": "H0",
"label": "Trash",
"type": "ROOT",
"class": "TRASH",
"expanded": true,
"import": null
"name": "Trash",
"itemAttr": {
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 3,
"type": "ROOT",
"class": "TRASH"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Delete Me!",
"type": "FILE",
"class": "NOVEL",
"expanded": false,
"active": true,
"layout": "DOCUMENT",
"charCount": 0,
"wordCount": 0,
"paraCount": 0,
"cursorPos": 36,
"status": "s000000"
"name": "Delete Me!",
"itemAttr": {
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"expanded": false,
"charCount": 0,
"wordCount": 0,
"paraCount": 0,
"cursorPos": 36
},
"nameAttr": {
"active": true,
"status": "s000000"
}
}
]
]
+433 -301
View File
@@ -1,346 +1,478 @@
[
{
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"heading": "H0",
"label": "Novel",
"type": "ROOT",
"class": "NOVEL",
"expanded": true,
"status": "s000002"
"name": "Novel",
"itemAttr": {
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"type": "ROOT",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000002"
}
},
{
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"heading": "H0",
"label": "Title Page",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 72,
"wordCount": 15,
"paraCount": 2,
"cursorPos": 78,
"status": "s000002"
"name": "Title Page",
"itemAttr": {
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 72,
"wordCount": 15,
"paraCount": 2,
"cursorPos": 78
},
"nameAttr": {
"active": true,
"status": "s000002"
}
},
{
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"heading": "H0",
"label": "Page",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 210,
"wordCount": 40,
"paraCount": 2,
"cursorPos": 213,
"status": "s000000"
"name": "Page",
"itemAttr": {
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 210,
"wordCount": 40,
"paraCount": 2,
"cursorPos": 213
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"heading": "H0",
"label": "Part One",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 23,
"wordCount": 5,
"paraCount": 1,
"cursorPos": 0,
"status": "s000000"
"name": "Part One",
"itemAttr": {
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 23,
"wordCount": 5,
"paraCount": 1,
"cursorPos": 0
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"heading": "H0",
"label": "A Folder",
"type": "FOLDER",
"class": "NOVEL",
"expanded": true,
"status": "s000003"
"name": "A Folder",
"itemAttr": {
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"type": "FOLDER",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000003"
}
},
{
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Chapter One",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 12,
"wordCount": 3,
"paraCount": 0,
"cursorPos": 215,
"status": "s000001"
"name": "Chapter One",
"itemAttr": {
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 12,
"wordCount": 3,
"paraCount": 0,
"cursorPos": 215
},
"nameAttr": {
"active": true,
"status": "s000001"
}
},
{
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"heading": "H0",
"label": "Making a Scene",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 1483,
"wordCount": 263,
"paraCount": 8,
"cursorPos": 1086,
"status": "s000003"
"name": "Making a Scene",
"itemAttr": {
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 1483,
"wordCount": 263,
"paraCount": 8,
"cursorPos": 1086
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"heading": "H0",
"label": "Another Scene",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 428,
"status": "s000003"
"name": "Another Scene",
"itemAttr": {
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 428
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"heading": "H0",
"label": "Interlude",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 633,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 1238,
"status": "s000006"
"name": "Interlude",
"itemAttr": {
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 633,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 1238
},
"nameAttr": {
"active": true,
"status": "s000006"
}
},
{
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"heading": "H0",
"label": "A Note on Structure",
"type": "FILE",
"class": "NOVEL",
"active": false,
"layout": "NOTE",
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1721,
"status": "s000004"
"name": "A Note on Structure",
"itemAttr": {
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"type": "FILE",
"class": "NOVEL",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1721
},
"nameAttr": {
"active": false,
"status": "s000004"
}
},
{
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"heading": "H0",
"label": "Chapter Two",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343,
"status": "s000003"
"name": "Chapter Two",
"itemAttr": {
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"heading": "H0",
"label": "We Found John!",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224,
"status": "s000003"
"name": "We Found John!",
"itemAttr": {
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"heading": "H0",
"label": "Characters",
"type": "ROOT",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Characters",
"itemAttr": {
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"type": "ROOT",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"heading": "H0",
"label": "Main Characters",
"type": "FOLDER",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Main Characters",
"itemAttr": {
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"type": "FOLDER",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"heading": "H0",
"label": "John Smith",
"type": "FILE",
"class": "CHARACTER",
"active": true,
"layout": "NOTE",
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24,
"import": "i000008"
"name": "John Smith",
"itemAttr": {
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"heading": "H0",
"label": "Jane Smith",
"type": "FILE",
"class": "CHARACTER",
"active": true,
"layout": "NOTE",
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25,
"import": "i000009"
"name": "Jane Smith",
"itemAttr": {
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"heading": "H0",
"label": "Locations",
"type": "ROOT",
"class": "WORLD",
"expanded": true,
"import": null
"name": "Locations",
"itemAttr": {
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"type": "ROOT",
"class": "WORLD"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"heading": "H0",
"label": "Earth",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20,
"import": "i00000a"
"name": "Earth",
"itemAttr": {
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20
},
"nameAttr": {
"active": true,
"import": "i00000a"
}
},
{
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"heading": "H0",
"label": "Space",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133,
"import": "i000008"
"name": "Space",
"itemAttr": {
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"heading": "H0",
"label": "Mars",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45,
"import": "i000009"
"name": "Mars",
"itemAttr": {
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 3,
"heading": "H0",
"label": "Trash",
"type": "ROOT",
"class": "TRASH",
"expanded": true,
"import": null
"name": "Trash",
"itemAttr": {
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 3,
"type": "ROOT",
"class": "TRASH"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Delete Me!",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 30,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 36,
"status": "s000000"
"name": "Delete Me!",
"itemAttr": {
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 30,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 36
},
"nameAttr": {
"active": true,
"status": "s000000"
}
}
]
]
+486 -336
View File
@@ -1,387 +1,537 @@
[
{
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"heading": "H0",
"label": "Novel",
"type": "ROOT",
"class": "NOVEL",
"expanded": true,
"status": "s000002"
"name": "Novel",
"itemAttr": {
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"type": "ROOT",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000002"
}
},
{
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"heading": "H0",
"label": "Title Page",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 241,
"wordCount": 42,
"paraCount": 3,
"cursorPos": 252,
"status": "s000002"
"name": "Title Page",
"itemAttr": {
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 241,
"wordCount": 42,
"paraCount": 3,
"cursorPos": 252
},
"nameAttr": {
"active": true,
"status": "s000002"
}
},
{
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"heading": "H0",
"label": "Page",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 125,
"wordCount": 26,
"paraCount": 2,
"cursorPos": 127,
"status": "s000000"
"name": "Page",
"itemAttr": {
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 125,
"wordCount": 26,
"paraCount": 2,
"cursorPos": 127
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"heading": "H0",
"label": "Part One",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 26,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 30,
"status": "s000000"
"name": "Part One",
"itemAttr": {
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 26,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 30
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"heading": "H0",
"label": "A Folder",
"type": "FOLDER",
"class": "NOVEL",
"expanded": true,
"status": "s000003"
"name": "A Folder",
"itemAttr": {
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"type": "FOLDER",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000003"
}
},
{
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Chapter One",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 75,
"wordCount": 14,
"paraCount": 1,
"cursorPos": 279,
"status": "s000001"
"name": "Chapter One",
"itemAttr": {
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 75,
"wordCount": 14,
"paraCount": 1,
"cursorPos": 279
},
"nameAttr": {
"active": true,
"status": "s000001"
}
},
{
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"heading": "H0",
"label": "Making a Scene",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 2429,
"wordCount": 432,
"paraCount": 14,
"cursorPos": 61,
"status": "s000003"
"name": "Making a Scene",
"itemAttr": {
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 2429,
"wordCount": 432,
"paraCount": 14,
"cursorPos": 61
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"heading": "H0",
"label": "Another Scene",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 577,
"status": "s000003"
"name": "Another Scene",
"itemAttr": {
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 577
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"heading": "H0",
"label": "Interlude",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 617,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 1137,
"status": "s000000"
"name": "Interlude",
"itemAttr": {
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 617,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 1137
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"heading": "H0",
"label": "A Note on Structure",
"type": "FILE",
"class": "NOVEL",
"active": false,
"layout": "NOTE",
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1110,
"status": "s000004"
"name": "A Note on Structure",
"itemAttr": {
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"type": "FILE",
"class": "NOVEL",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1110
},
"nameAttr": {
"active": false,
"status": "s000004"
}
},
{
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"heading": "H0",
"label": "Chapter Two",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343,
"status": "s000003"
"name": "Chapter Two",
"itemAttr": {
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"heading": "H0",
"label": "We Found John!",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224,
"status": "s000003"
"name": "We Found John!",
"itemAttr": {
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"heading": "H0",
"label": "Characters",
"type": "ROOT",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Characters",
"itemAttr": {
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"type": "ROOT",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"heading": "H0",
"label": "Main Characters",
"type": "FOLDER",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Main Characters",
"itemAttr": {
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"type": "FOLDER",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"heading": "H0",
"label": "John Smith",
"type": "FILE",
"class": "CHARACTER",
"active": true,
"layout": "NOTE",
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24,
"import": "i000008"
"name": "John Smith",
"itemAttr": {
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"heading": "H0",
"label": "Jane Smith",
"type": "FILE",
"class": "CHARACTER",
"active": true,
"layout": "NOTE",
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25,
"import": "i000009"
"name": "Jane Smith",
"itemAttr": {
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"heading": "H0",
"label": "Locations",
"type": "ROOT",
"class": "WORLD",
"expanded": true,
"import": null
"name": "Locations",
"itemAttr": {
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"type": "ROOT",
"class": "WORLD"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"heading": "H0",
"label": "Earth",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20,
"import": "i00000a"
"name": "Earth",
"itemAttr": {
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20
},
"nameAttr": {
"active": true,
"import": "i00000a"
}
},
{
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"heading": "H0",
"label": "Space",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133,
"import": "i000008"
"name": "Space",
"itemAttr": {
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"heading": "H0",
"label": "Mars",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45,
"import": "i000009"
"name": "Mars",
"itemAttr": {
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "6827118336ac1",
"parent": null,
"root": null,
"order": 3,
"heading": "H0",
"label": "Outtakes",
"type": "ROOT",
"class": "ARCHIVE",
"expanded": true,
"status": null
"name": "Outtakes",
"itemAttr": {
"handle": "6827118336ac1",
"parent": null,
"root": null,
"order": 3,
"type": "ROOT",
"class": "ARCHIVE"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": null
}
},
{
"handle": "ae9bf3c3ea159",
"parent": "6827118336ac1",
"root": null,
"order": 0,
"heading": "H0",
"label": "Scenes",
"type": "FOLDER",
"class": "ARCHIVE",
"expanded": true,
"status": null
"name": "Scenes",
"itemAttr": {
"handle": "ae9bf3c3ea159",
"parent": "6827118336ac1",
"root": null,
"order": 0,
"type": "FOLDER",
"class": "ARCHIVE"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": null
}
},
{
"handle": "8a5deb88c0e97",
"parent": "ae9bf3c3ea159",
"root": null,
"order": 0,
"heading": "H0",
"label": "Old File",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 315,
"wordCount": 55,
"paraCount": 1,
"cursorPos": 322,
"status": "s000003"
"name": "Old File",
"itemAttr": {
"handle": "8a5deb88c0e97",
"parent": "ae9bf3c3ea159",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 315,
"wordCount": 55,
"paraCount": 1,
"cursorPos": 322
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 4,
"heading": "H0",
"label": "Trash",
"type": "ROOT",
"class": "TRASH",
"expanded": true,
"import": null
"name": "Trash",
"itemAttr": {
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 4,
"type": "ROOT",
"class": "TRASH"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Delete Me!",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 30,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 36,
"status": "s000000"
"name": "Delete Me!",
"itemAttr": {
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 30,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 36
},
"nameAttr": {
"active": true,
"status": "s000000"
}
}
]
]
+486 -336
View File
@@ -1,387 +1,537 @@
[
{
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"heading": "H0",
"label": "Novel",
"type": "ROOT",
"class": "NOVEL",
"expanded": true,
"status": "s000002"
"name": "Novel",
"itemAttr": {
"handle": "7031beac91f75",
"parent": null,
"root": null,
"order": 0,
"type": "ROOT",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000002"
}
},
{
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"heading": "H0",
"label": "Title Page",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 93,
"wordCount": 19,
"paraCount": 2,
"cursorPos": 2,
"status": "s000002"
"name": "Title Page",
"itemAttr": {
"handle": "53b69b83cdafc",
"parent": "7031beac91f75",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 93,
"wordCount": 19,
"paraCount": 2,
"cursorPos": 2
},
"nameAttr": {
"active": true,
"status": "s000002"
}
},
{
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"heading": "H0",
"label": "Page",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 186,
"wordCount": 39,
"paraCount": 2,
"cursorPos": 212,
"status": "s000000"
"name": "Page",
"itemAttr": {
"handle": "974e400180a99",
"parent": "7031beac91f75",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 186,
"wordCount": 39,
"paraCount": 2,
"cursorPos": 212
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"heading": "H0",
"label": "Part One",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 26,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 33,
"status": "s000000"
"name": "Part One",
"itemAttr": {
"handle": "edca4be2fcaf8",
"parent": "7031beac91f75",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 26,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 33
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"heading": "H0",
"label": "A Folder",
"type": "FOLDER",
"class": "NOVEL",
"expanded": true,
"status": "s000003"
"name": "A Folder",
"itemAttr": {
"handle": "e7ded148d6e4a",
"parent": "7031beac91f75",
"root": null,
"order": 3,
"type": "FOLDER",
"class": "NOVEL"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000003"
}
},
{
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Chapter One",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 75,
"wordCount": 14,
"paraCount": 1,
"cursorPos": 279,
"status": "s000001"
"name": "Chapter One",
"itemAttr": {
"handle": "6a2d6d5f4f401",
"parent": "e7ded148d6e4a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 75,
"wordCount": 14,
"paraCount": 1,
"cursorPos": 279
},
"nameAttr": {
"active": true,
"status": "s000001"
}
},
{
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"heading": "H0",
"label": "Making a Scene",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 2429,
"wordCount": 432,
"paraCount": 14,
"cursorPos": 62,
"status": "s000003"
"name": "Making a Scene",
"itemAttr": {
"handle": "636b6aa9b697b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 2429,
"wordCount": 432,
"paraCount": 14,
"cursorPos": 62
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"heading": "H0",
"label": "Another Scene",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 577,
"status": "s000003"
"name": "Another Scene",
"itemAttr": {
"handle": "bc0cbd2a407f3",
"parent": "e7ded148d6e4a",
"root": null,
"order": 2,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 476,
"wordCount": 93,
"paraCount": 3,
"cursorPos": 577
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"heading": "H0",
"label": "Interlude",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 617,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 4,
"status": "s000000"
"name": "Interlude",
"itemAttr": {
"handle": "ba8a28a246524",
"parent": "e7ded148d6e4a",
"root": null,
"order": 3,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 617,
"wordCount": 101,
"paraCount": 3,
"cursorPos": 4
},
"nameAttr": {
"active": true,
"status": "s000000"
}
},
{
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"heading": "H0",
"label": "A Note on Structure",
"type": "FILE",
"class": "NOVEL",
"active": false,
"layout": "NOTE",
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1110,
"status": "s000004"
"name": "A Note on Structure",
"itemAttr": {
"handle": "96b68994dfa3d",
"parent": "e7ded148d6e4a",
"root": null,
"order": 4,
"type": "FILE",
"class": "NOVEL",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 1692,
"wordCount": 313,
"paraCount": 6,
"cursorPos": 1110
},
"nameAttr": {
"active": false,
"status": "s000004"
}
},
{
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"heading": "H0",
"label": "Chapter Two",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343,
"status": "s000003"
"name": "Chapter Two",
"itemAttr": {
"handle": "88706ddc78b1b",
"parent": "e7ded148d6e4a",
"root": null,
"order": 5,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 139,
"wordCount": 28,
"paraCount": 1,
"cursorPos": 343
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"heading": "H0",
"label": "We Found John!",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224,
"status": "s000003"
"name": "We Found John!",
"itemAttr": {
"handle": "ae7339df26ded",
"parent": "e7ded148d6e4a",
"root": null,
"order": 6,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 189,
"wordCount": 37,
"paraCount": 1,
"cursorPos": 224
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"heading": "H0",
"label": "Characters",
"type": "ROOT",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Characters",
"itemAttr": {
"handle": "f6622b4617424",
"parent": null,
"root": null,
"order": 1,
"type": "ROOT",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"heading": "H0",
"label": "Main Characters",
"type": "FOLDER",
"class": "CHARACTER",
"expanded": true,
"import": null
"name": "Main Characters",
"itemAttr": {
"handle": "f7e2d9f330615",
"parent": "f6622b4617424",
"root": null,
"order": 0,
"type": "FOLDER",
"class": "CHARACTER"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"heading": "H0",
"label": "John Smith",
"type": "FILE",
"class": "CHARACTER",
"active": true,
"layout": "NOTE",
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24,
"import": "i000008"
"name": "John Smith",
"itemAttr": {
"handle": "14298de4d9524",
"parent": "f7e2d9f330615",
"root": null,
"order": 0,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 49,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 24
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"heading": "H0",
"label": "Jane Smith",
"type": "FILE",
"class": "CHARACTER",
"active": true,
"layout": "NOTE",
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25,
"import": "i000009"
"name": "Jane Smith",
"itemAttr": {
"handle": "bb2c23b3c42cc",
"parent": "f7e2d9f330615",
"root": null,
"order": 1,
"type": "FILE",
"class": "CHARACTER",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 55,
"wordCount": 9,
"paraCount": 1,
"cursorPos": 25
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"heading": "H0",
"label": "Locations",
"type": "ROOT",
"class": "WORLD",
"expanded": true,
"import": null
"name": "Locations",
"itemAttr": {
"handle": "15c4492bd5107",
"parent": null,
"root": null,
"order": 2,
"type": "ROOT",
"class": "WORLD"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"heading": "H0",
"label": "Earth",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20,
"import": "i00000a"
"name": "Earth",
"itemAttr": {
"handle": "b3e74dbc1f584",
"parent": "15c4492bd5107",
"root": null,
"order": 0,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 76,
"wordCount": 15,
"paraCount": 1,
"cursorPos": 20
},
"nameAttr": {
"active": true,
"import": "i00000a"
}
},
{
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"heading": "H0",
"label": "Space",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133,
"import": "i000008"
"name": "Space",
"itemAttr": {
"handle": "f1471bef9f2ae",
"parent": "15c4492bd5107",
"root": null,
"order": 1,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 115,
"wordCount": 24,
"paraCount": 1,
"cursorPos": 133
},
"nameAttr": {
"active": true,
"import": "i000008"
}
},
{
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"heading": "H0",
"label": "Mars",
"type": "FILE",
"class": "WORLD",
"active": true,
"layout": "NOTE",
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45,
"import": "i000009"
"name": "Mars",
"itemAttr": {
"handle": "5eaea4e8cdee8",
"parent": "15c4492bd5107",
"root": null,
"order": 2,
"type": "FILE",
"class": "WORLD",
"layout": "NOTE"
},
"metaAttr": {
"heading": "H0",
"charCount": 28,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 45
},
"nameAttr": {
"active": true,
"import": "i000009"
}
},
{
"handle": "6827118336ac1",
"parent": null,
"root": null,
"order": 3,
"heading": "H0",
"label": "Archive",
"type": "ROOT",
"class": "ARCHIVE",
"expanded": true,
"status": "s000000"
"name": "Archive",
"itemAttr": {
"handle": "6827118336ac1",
"parent": null,
"root": null,
"order": 3,
"type": "ROOT",
"class": "ARCHIVE"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000000"
}
},
{
"handle": "ae9bf3c3ea159",
"parent": "6827118336ac1",
"root": null,
"order": 0,
"heading": "H0",
"label": "Scenes",
"type": "FOLDER",
"class": "ARCHIVE",
"expanded": true,
"status": "s000000"
"name": "Scenes",
"itemAttr": {
"handle": "ae9bf3c3ea159",
"parent": "6827118336ac1",
"root": null,
"order": 0,
"type": "FOLDER",
"class": "ARCHIVE"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"status": "s000000"
}
},
{
"handle": "8a5deb88c0e97",
"parent": "ae9bf3c3ea159",
"root": null,
"order": 0,
"heading": "H0",
"label": "Old File",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 314,
"wordCount": 55,
"paraCount": 1,
"cursorPos": 322,
"status": "s000003"
"name": "Old File",
"itemAttr": {
"handle": "8a5deb88c0e97",
"parent": "ae9bf3c3ea159",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 314,
"wordCount": 55,
"paraCount": 1,
"cursorPos": 322
},
"nameAttr": {
"active": true,
"status": "s000003"
}
},
{
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 4,
"heading": "H0",
"label": "Trash",
"type": "ROOT",
"class": "TRASH",
"expanded": true,
"import": null
"name": "Trash",
"itemAttr": {
"handle": "98acd8c76c93a",
"parent": null,
"root": null,
"order": 4,
"type": "ROOT",
"class": "TRASH"
},
"metaAttr": {
"heading": "H0",
"expanded": true
},
"nameAttr": {
"import": null
}
},
{
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"heading": "H0",
"label": "Delete Me!",
"type": "FILE",
"class": "NOVEL",
"active": true,
"layout": "DOCUMENT",
"charCount": 30,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 36,
"status": "s000000"
"name": "Delete Me!",
"itemAttr": {
"handle": "b8136a5a774a0",
"parent": "98acd8c76c93a",
"root": null,
"order": 0,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT"
},
"metaAttr": {
"heading": "H0",
"charCount": 30,
"wordCount": 6,
"paraCount": 1,
"cursorPos": 36
},
"nameAttr": {
"active": true,
"status": "s000000"
}
}
]
]
+69 -51
View File
@@ -509,23 +509,29 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
# File
theItem = NWItem(theProject)
assert theItem.unpack({
"label": "A File",
"handle": "0000000000003",
"parent": "0000000000002",
"root": "0000000000001",
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT",
"expanded": True,
"status": None,
"import": None,
"heading": "H1",
"charCount": 100,
"wordCount": 20,
"paraCount": 2,
"cursorPos": 50,
"active": False,
"name": "A File",
"itemAttr": {
"handle": "0000000000003",
"parent": "0000000000002",
"root": "0000000000001",
"order": 1,
"type": "FILE",
"class": "NOVEL",
"layout": "DOCUMENT",
},
"metaAttr": {
"expanded": True,
"heading": "H1",
"charCount": 100,
"wordCount": 20,
"paraCount": 2,
"cursorPos": 50,
},
"nameAttr": {
"status": None,
"import": None,
"active": False,
},
}) is True
assert theItem.itemName == "A File"
@@ -575,23 +581,29 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
# Folder
theItem = NWItem(theProject)
assert theItem.unpack({
"label": "A Folder",
"handle": "0000000000003",
"parent": "0000000000002",
"root": "0000000000001",
"order": 1,
"type": "FOLDER",
"class": "NOVEL",
"layout": "DOCUMENT",
"expanded": True,
"status": "",
"import": "",
"heading": "H1",
"charCount": 100,
"wordCount": 20,
"paraCount": 2,
"cursorPos": 50,
"active": True,
"name": "A Folder",
"itemAttr": {
"handle": "0000000000003",
"parent": "0000000000002",
"root": "0000000000001",
"order": 1,
"type": "FOLDER",
"class": "NOVEL",
"layout": "DOCUMENT",
},
"metaAttr": {
"expanded": True,
"heading": "H1",
"charCount": 100,
"wordCount": 20,
"paraCount": 2,
"cursorPos": 50,
},
"nameAttr": {
"status": "",
"import": "",
"active": True,
}
}) is True
assert theItem.itemName == "A Folder"
@@ -634,23 +646,29 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
# Root
theItem = NWItem(theProject)
assert theItem.unpack({
"label": "A Novel",
"handle": "0000000000003",
"parent": "0000000000002",
"root": "0000000000001",
"order": 1,
"type": "ROOT",
"class": "NOVEL",
"layout": "DOCUMENT",
"expanded": True,
"status": None,
"import": None,
"heading": "H1",
"charCount": 100,
"wordCount": 20,
"paraCount": 2,
"cursorPos": 50,
"active": True,
"name": "A Novel",
"itemAttr": {
"handle": "0000000000003",
"parent": "0000000000002",
"root": "0000000000001",
"order": 1,
"type": "ROOT",
"class": "NOVEL",
"layout": "DOCUMENT",
},
"metaAttr": {
"expanded": True,
"heading": "H1",
"charCount": 100,
"wordCount": 20,
"paraCount": 2,
"cursorPos": 50,
},
"nameAttr": {
"status": None,
"import": None,
"active": True,
},
}) is True
assert theItem.itemName == "A Novel"
+22 -12
View File
@@ -19,11 +19,11 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import json
import os
import json
import pytest
import shutil
from shutil import copyfile
from datetime import datetime
from mock import causeOSError
@@ -47,6 +47,7 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, filesDir, fncDir, outDir, refDir
xmlFile = os.path.join(fncDir, "nwProject-1.4.nwx")
bakFile = os.path.join(fncDir, "nwProject-1.4.bak")
outFile = os.path.join(fncDir, "nwProject.nwx")
tstFile = os.path.join(outDir, "ProjectXML_ReadCurrent.nwx")
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
@@ -125,7 +126,7 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, filesDir, fncDir, outDir, refDir
content = []
# Parse a valid, complete file
shutil.copy(refFile, xmlFile)
copyfile(refFile, xmlFile)
assert xmlReader.read(data, content) is True
assert xmlReader.state == XMLReadState.PARSED_OK
assert xmlReader.xmlRoot == "novelWriterXML"
@@ -231,7 +232,8 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, filesDir, fncDir, outDir, refDir
# Successful save (should be twice)
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
assert cmpFiles(outFile, xmlFile)
copyfile(outFile, tstFile)
assert cmpFiles(tstFile, xmlFile)
# END Test testCoreProjectXML_ReadCurrent
@@ -243,7 +245,7 @@ def testCoreProjectXML_ReadLegacy10(filesDir, fncDir, outDir, refDir, mockRnd):
refFile = os.path.join(filesDir, "nwProject-1.0.nwx")
xmlFile = os.path.join(fncDir, "nwProject-1.0.nwx")
outFile = os.path.join(fncDir, "nwProject.nwx")
shutil.copy(refFile, xmlFile)
copyfile(refFile, xmlFile)
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
@@ -369,8 +371,10 @@ def testCoreProjectXML_ReadLegacy10(filesDir, fncDir, outDir, refDir, mockRnd):
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncDir)
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = os.path.join(outDir, "projectXML_ReadLegacy10.nwx")
compFile = os.path.join(refDir, "projectXML_ReadLegacy10.nwx")
assert cmpFiles(outFile, compFile)
copyfile(outFile, testFile)
assert cmpFiles(testFile, compFile)
# END Test testCoreProjectXML_ReadLegacy10
@@ -382,7 +386,7 @@ def testCoreProjectXML_ReadLegacy11(filesDir, fncDir, outDir, refDir, mockRnd):
refFile = os.path.join(filesDir, "nwProject-1.1.nwx")
xmlFile = os.path.join(fncDir, "nwProject-1.1.nwx")
outFile = os.path.join(fncDir, "nwProject.nwx")
shutil.copy(refFile, xmlFile)
copyfile(refFile, xmlFile)
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
@@ -508,8 +512,10 @@ def testCoreProjectXML_ReadLegacy11(filesDir, fncDir, outDir, refDir, mockRnd):
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncDir)
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = os.path.join(outDir, "projectXML_ReadLegacy11.nwx")
compFile = os.path.join(refDir, "projectXML_ReadLegacy11.nwx")
assert cmpFiles(outFile, compFile)
copyfile(outFile, testFile)
assert cmpFiles(testFile, compFile)
# END Test testCoreProjectXML_ReadLegacy11
@@ -521,7 +527,7 @@ def testCoreProjectXML_ReadLegacy12(filesDir, fncDir, outDir, refDir, mockRnd):
refFile = os.path.join(filesDir, "nwProject-1.2.nwx")
xmlFile = os.path.join(fncDir, "nwProject-1.2.nwx")
outFile = os.path.join(fncDir, "nwProject.nwx")
shutil.copy(refFile, xmlFile)
copyfile(refFile, xmlFile)
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
@@ -650,8 +656,10 @@ def testCoreProjectXML_ReadLegacy12(filesDir, fncDir, outDir, refDir, mockRnd):
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncDir)
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = os.path.join(outDir, "projectXML_ReadLegacy12.nwx")
compFile = os.path.join(refDir, "projectXML_ReadLegacy12.nwx")
assert cmpFiles(outFile, compFile)
copyfile(outFile, testFile)
assert cmpFiles(testFile, compFile)
# END Test testCoreProjectXML_ReadLegacy12
@@ -663,7 +671,7 @@ def testCoreProjectXML_ReadLegacy13(filesDir, fncDir, outDir, refDir, mockRnd):
refFile = os.path.join(filesDir, "nwProject-1.3.nwx")
xmlFile = os.path.join(fncDir, "nwProject-1.3.nwx")
outFile = os.path.join(fncDir, "nwProject.nwx")
shutil.copy(refFile, xmlFile)
copyfile(refFile, xmlFile)
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
@@ -792,7 +800,9 @@ def testCoreProjectXML_ReadLegacy13(filesDir, fncDir, outDir, refDir, mockRnd):
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncDir)
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = os.path.join(outDir, "projectXML_ReadLegacy13.nwx")
compFile = os.path.join(refDir, "projectXML_ReadLegacy13.nwx")
assert cmpFiles(outFile, compFile)
copyfile(outFile, testFile)
assert cmpFiles(testFile, compFile)
# END Test testCoreProjectXML_ReadLegacy13