diff --git a/app.py b/app.py index 1a5a197..5a66371 100755 --- a/app.py +++ b/app.py @@ -250,7 +250,8 @@ def loadPrefs(self): 'displayArrows' : True, 'createPassagePrompt' : True, 'importImagePrompt' : True, - 'passageWarnings' : True + 'passageWarnings' : True, + 'saveTwinePosition' : False }.iteritems(): if not sc.HasEntry(k): if type(v) == str: diff --git a/prefframe.py b/prefframe.py index f466eeb..5174b21 100644 --- a/prefframe.py +++ b/prefframe.py @@ -15,7 +15,7 @@ def __init__(self, app, parent = None): panel = wx.Panel(parent = self, id = wx.ID_ANY) borderSizer = wx.BoxSizer(wx.VERTICAL) panel.SetSizer(borderSizer) - panelSizer = wx.FlexGridSizer(14, 2, metrics.size('relatedControls'), metrics.size('relatedControls')) + panelSizer = wx.FlexGridSizer(15, 2, metrics.size('relatedControls'), metrics.size('relatedControls')) borderSizer.Add(panelSizer, flag = wx.ALL, border = metrics.size('windowBorder')) self.editorFont = wx.FontPickerCtrl(panel, style = wx.FNTP_FONTDESC_AS_LABEL) @@ -67,6 +67,7 @@ def checkbox(self, name, label, panel=panel): checkbox(self, "createPassagePrompt", 'Offer to create new passages for broken links') checkbox(self, "importImagePrompt", 'Offer to import externally linked images') checkbox(self, "passageWarnings", 'Warn about possible passage code errors') + checkbox(self, "saveTwinePosition", 'Save twine position data in twee source') panelSizer.Add(wx.StaticText(panel, label = 'Normal Font'), flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(self.editorFont) @@ -96,6 +97,8 @@ def checkbox(self, name, label, panel=panel): panelSizer.Add(self.importImagePrompt) # pylint: disable=no-member panelSizer.Add((1,2)) panelSizer.Add(self.passageWarnings) # pylint: disable=no-member + panelSizer.Add((1,2)) + panelSizer.Add(self.saveTwinePosition) # pylint: disable=no-member panelSizer.Fit(self) borderSizer.Fit(self) diff --git a/storyframe.py b/storyframe.py index a480e09..ced4907 100644 --- a/storyframe.py +++ b/storyframe.py @@ -542,10 +542,12 @@ def exportSource(self, event=None): path = dialog.GetPath() tw = TiddlyWiki() - for widget in self.storyPanel.widgetDict.itervalues(): tw.addTiddler(widget.passage) + for widget in self.storyPanel.widgetDict.itervalues(): + widget.passage.pos = widget.pos + tw.addTiddler(widget.passage) dest = codecs.open(path, 'w', 'utf-8-sig', 'replace') order = [widget.passage.title for widget in self.storyPanel.sortedWidgets()] - dest.write(tw.toTwee(order)) + dest.write(tw.toTwee(order, self.app.config.ReadBool('saveTwinePosition'))) dest.close() except: self.app.displayError('exporting your source code') diff --git a/tiddlywiki.py b/tiddlywiki.py index 3ea1762..5b53dd6 100644 --- a/tiddlywiki.py +++ b/tiddlywiki.py @@ -25,16 +25,18 @@ def __init__(self, author = 'twee'): def hasTiddler(self, name): return name in self.tiddlers - def toTwee(self, order = None): + def toTwee(self, order = None, saveTwinePosition=False): """Returns Twee source code for this TiddlyWiki. The 'order' argument is a sequence of passage titles specifying the order in which passages should appear in the output string; by default passages are returned in arbitrary order. + If saveTwinePosition is True the twee source code will include metadata + with the location of the passage in the twine storypanel. """ tiddlers = self.tiddlers if order is None: order = tiddlers.keys() - return u''.join(tiddlers[i].toTwee() for i in order) + return u''.join(tiddlers[i].toTwee(saveTwinePosition) for i in order) def read(self, filename): try: @@ -390,7 +392,30 @@ def initTwee(self, source): tag_bits = meta_bits[1].split(' ') for tag in tag_bits: - self.tags.append(tag.strip('[]')) + stripped_tag = tag.strip('[] ') + if not stripped_tag: + continue + self.tags.append(stripped_tag) + + if len(meta_bits) > 2: + pos_bits = meta_bits[2].split(',') + + for pos_key in pos_bits: + stripped_pos = pos_key.strip('[]') + keyval_bits = stripped_pos.split(':') + if len(keyval_bits) == 2: + key = keyval_bits[0].strip() + val = keyval_bits[1].strip() + if key == 'twine-pos-x': + try: + self.pos[0] = float(val) + except ValueError: + continue + elif key == 'twine-pos-y': + try: + self.pos[1] = float(val) + except ValueError: + continue # and then the body text @@ -511,8 +536,10 @@ def applyRot13(text): ) - def toTwee(self): - """Returns a Twee representation of this tiddler.""" + def toTwee(self, saveTwinePosition=False): + """Returns a Twee representation of this tiddler. If saveTwinePosition is + True the location of the passagewidget will be stored in the twee source. + """ output = u':: ' + self.title if len(self.tags) > 0: @@ -521,6 +548,10 @@ def toTwee(self): output += tag + ' ' output = output.strip() output += u']' + elif saveTwinePosition: + output += u' []' + if saveTwinePosition: + output += u'[twine-pos-x:%s, twine-pos-y:%s]' % (self.pos[0], self.pos[1]) output += u"\n" + self.text + u"\n\n\n" return output