Example #1
0
    def proof(self, event=None):
        """
        Builds an RTF version of the story. Pass whether to open the destination file afterwards.
        """

        # ask for our destination

        dialog = wx.FileDialog(self, 'Proof Story', os.getcwd(), "", \
                         "RTF Document (*.rtf)|*.rtf", \
                           wx.SAVE | wx.FD_OVERWRITE_PROMPT | wx.FD_CHANGE_DIR)

        if dialog.ShowModal() == wx.ID_OK:
            path = dialog.GetPath()
            dialog.Destroy()
        else:
            dialog.Destroy()
            return

        try:
            # open destination for writing

            dest = open(path, 'w')

            # assemble our tiddlywiki and write it out

            tw = TiddlyWiki()
            for widget in self.storyPanel.sortedWidgets():
                tw.addTiddler(widget.passage)

            order = map(lambda w: w.passage.title,
                        self.storyPanel.sortedWidgets())
            dest.write(tw.toRtf(order))
            dest.close()
        except:
            self.app.displayError('building a proofing copy of your story')
Example #2
0
    def exportSource(self, event=None):
        """Asks the user to choose a file to export source to, then exports the wiki."""
        dialog = wx.FileDialog(
            self,
            "Export Source Code",
            os.getcwd(),
            "",
            "Text File (*.txt)|*.txt",
            wx.SAVE | wx.FD_OVERWRITE_PROMPT | wx.FD_CHANGE_DIR,
        )
        if dialog.ShowModal() == wx.ID_OK:
            try:
                path = dialog.GetPath()
                tw = TiddlyWiki()

                for widget in self.storyPanel.widgets:
                    tw.addTiddler(widget.passage)
                dest = open(path, "w")
                order = map(lambda w: w.passage.title, self.storyPanel.sortedWidgets())
                dest.write(tw.toTwee(order))
                dest.close()
            except:
                self.app.displayError("exporting your source code")

        dialog.Destroy()
Example #3
0
 def importHtml (self, event = None):
     """Asks the user to choose a file to import HTML tiddlers from, then imports into the current story."""
     dialog = wx.FileDialog(self, 'Import From Compiled HTML', os.getcwd(), '', \
                            'HTML Twine game (*.html;* .htm; *.txt)|*.html;*.htm;*.txt|All Files (*.*)|*.*', wx.OPEN | wx.FD_CHANGE_DIR)
     
     if dialog.ShowModal() == wx.ID_OK:
         try:
             # have a TiddlyWiki object parse it for us
             tw = TiddlyWiki()
             tw.addHtmlFromFilename(dialog.GetPath())
             
             # add passages for each of the tiddlers the TiddlyWiki saw
             if len(tw.tiddlers):
                 lastpos = [0, 0]
                 for t in tw.tiddlers:
                     tiddler = tw.tiddlers[t]
                     new = self.storyPanel.newWidget(title = tiddler.title, text = tiddler.text, \
                                                     pos = tiddler.pos if tiddler.pos != None else lastpos, \
                                                     logicals = True, quietly = True)
                     lastpos = new.pos
                     new.passage.tags = tiddler.tags
                 self.setDirty(True, 'Import')
             else:
                 dialog = wx.MessageDialog(self, 'No passages were found in this file. Make sure ' + \
                                           'this is a Twine game file.', 'No Passages Found', \
                                           wx.ICON_INFORMATION | wx.OK)
                 dialog.ShowModal()
         except:
             self.app.displayError('importing from HTML') 
Example #4
0
 def importSource (self, event = None):
     """Asks the user to choose a file to import source from, then imports into the current story."""
     dialog = wx.FileDialog(self, 'Import Source Code', os.getcwd(), '', \
                            'Twee File (*.twee;* .tw; *.txt)|*.twee;*.tw;*.txt|All Files (*.*)|*.*', wx.OPEN | wx.FD_CHANGE_DIR)
     
     if dialog.ShowModal() == wx.ID_OK:
         try:
             # have a TiddlyWiki object parse it for us
             tw = TiddlyWiki()
             tw.addTweeFromFilename(dialog.GetPath())
             
             # add passages for each of the tiddlers the TiddlyWiki saw
             if len(tw.tiddlers):
                 lastpos = [0, 0]
                 for t in tw.tiddlers:
                     tiddler = tw.tiddlers[t]
                     new = self.storyPanel.newWidget(title = tiddler.title, text = tiddler.text, quietly = True, pos = lastpos)
                     new.passage.tags = tiddler.tags
                     lastpos = new.pos
                 self.setDirty(True, 'Import')
             else:
                 dialog = wx.MessageDialog(self, 'No passages were found in this file. Make sure ' + \
                                           'this is a Twee source file.', 'No Passages Found', \
                                           wx.ICON_INFORMATION | wx.OK)
                 dialog.ShowModal()
         except:
             self.app.displayError('importing your source code')
Example #5
0
    def importSource(self, event=None):
        """Asks the user to choose a file to import source from, then imports into the current story."""
        dialog = wx.FileDialog(self, 'Import Source Code', os.getcwd(), '', \
                               'Twee File (*.twee;* .tw; *.txt)|*.twee;*.tw;*.txt|All Files (*.*)|*.*', wx.OPEN | wx.FD_CHANGE_DIR)

        if dialog.ShowModal() == wx.ID_OK:
            try:
                # have a TiddlyWiki object parse it for us
                tw = TiddlyWiki()
                tw.addTweeFromFilename(dialog.GetPath())

                # add passages for each of the tiddlers the TiddlyWiki saw

                if len(tw.tiddlers):
                    for t in tw.tiddlers:
                        tiddler = tw.tiddlers[t]
                        new = self.storyPanel.newWidget(title=tiddler.title,
                                                        text=tiddler.text,
                                                        quietly=True)
                        new.tags = tiddler.tags
                    self.setDirty(True, 'Import')
                else:
                    dialog = wx.MessageDialog(self, 'No passages were found in this file. Make sure ' + \
                                              'this is a Twee source file.', 'No Passages Found', \
                                              wx.ICON_INFO | wx.OK)
                    dialog.ShowModal()
            except:
                self.app.displayError('importing your source code')
Example #6
0
    def proof (self, event = None):
        """
        Builds an RTF version of the story. Pass whether to open the destination file afterwards.
        """
           
        # ask for our destination
        
        dialog = wx.FileDialog(self, 'Proof Story', os.getcwd(), "", \
                         "RTF Document (*.rtf)|*.rtf", \
                           wx.SAVE | wx.FD_OVERWRITE_PROMPT | wx.FD_CHANGE_DIR)
        
        if dialog.ShowModal() == wx.ID_OK:
            path = dialog.GetPath()
            dialog.Destroy()
        else:
            dialog.Destroy()
            return
        
        try:
            # open destination for writing
        
            dest = open(path, 'w')
            
            # assemble our tiddlywiki and write it out
            
            tw = TiddlyWiki()
            for widget in self.storyPanel.sortedWidgets():
                tw.addTiddler(widget.passage)

            order = map(lambda w: w.passage.title, self.storyPanel.sortedWidgets())            
            dest.write(tw.toRtf(order))
            dest.close()
        except:
            self.app.displayError('building a proofing copy of your story')
Example #7
0
def getPlugins(repo, store):
	"""
	retrieve and store plugins from repository

	@param repo (list): repository dictionaries
	@param store (Store): TiddlyWeb store
	@return (bool): success
	"""
	if repo["type"] == "TiddlyWiki":
		try:
			html = urlopen(repo["URI"]).read() # TODO: deferred processing?!
			log.append("STATUS: retrieved repository '%s' (%s)" % (repo["name"], repo["URI"]))
		except IOError:
			log.append("ERROR: could not process repository '%s'" % repo["name"])
			return False
		bag = Bag(repo["name"])
		tw = TiddlyWiki(html)
		tw.convertStoreFormat()
		plugins = tw.getPluginTiddlers(repo)
		empty = "<html><body><div id='storeArea'>\n</div></body></html>" # XXX: ugly hack; cf. tiddlywiki.TiddlyWiki.getPluginTiddlers()
		if plugins != empty:
			savePlugins(store, bag)
			import_wiki(store, plugins, bag.name)
			return True
		else:
			log.append("WARNING: repository '%s' does not contain any plugins" % repo["name"])
			return False
	elif repo["type"] == "SVN":
		bag = Bag(repo["name"])
		svn = DirScraper(repo["URI"])
		try:
			plugins = svn.getPlugins("./", True)
			log.append("STATUS: retrieved repository '%s' (%s)" % (repo["name"], repo["URI"]))
		except IOError:
			log.append("ERROR: could not process repository '%s'" % repo["name"])
			return False
		if plugins:
			savePlugins(store, bag)
			for plugin in plugins:
				plugin.bag = bag.name
				store.put(plugin)
			return True
		else:
			log.append("WARNING: repository '%s' contains no plugins" % repo["name"])
			return False
	else:
		pass # XXX: TBD
Example #8
0
    def exportSource (self, event = None):
        """Asks the user to choose a file to export source to, then exports the wiki."""
        dialog = wx.FileDialog(self, 'Export Source Code', os.getcwd(), "", \
                               'Twee File (*.twee;* .tw; *.txt)|*.twee;*.tw;*.txt|All Files (*.*)|*.*', wx.SAVE | wx.FD_OVERWRITE_PROMPT | wx.FD_CHANGE_DIR)
        if dialog.ShowModal() == wx.ID_OK:
            try:
                path = dialog.GetPath()
                tw = TiddlyWiki()
                
                for widget in self.storyPanel.widgets: tw.addTiddler(widget.passage)
                dest = codecs.open(path, 'w', 'utf-8-sig', 'replace')
                order = map(lambda w: w.passage.title, self.storyPanel.sortedWidgets())
                dest.write(tw.toTwee(order))
                dest.close()
            except:
                self.app.displayError('exporting your source code')

        dialog.Destroy()
Example #9
0
	def build (self):
		tw = TiddlyWiki('twee')
		
		dest = open(self.destination, 'w')
		
		for source in self.sources:
			file = open(source)		
			tw.add_twee(file.read())
			file.close()

		header = open(self.getTargetPath() + self.target + os.sep + 'header.html')
		dest.write(header.read())
		header.close()
		
		dest.write(tw.to_html())
		dest.write('</div></html>')
		dest.close()
		
		return True
Example #10
0
    def exportSource(self, event=None):
        """Asks the user to choose a file to export source to, then exports the wiki."""
        dialog = wx.FileDialog(self, 'Export Source Code', os.getcwd(), "", \
                               'Twee File (*.twee;* .tw; *.txt)|*.twee;*.tw;*.txt|All Files (*.*)|*.*', wx.SAVE | wx.FD_OVERWRITE_PROMPT | wx.FD_CHANGE_DIR)
        if dialog.ShowModal() == wx.ID_OK:
            try:
                path = dialog.GetPath()
                tw = TiddlyWiki()

                for widget in self.storyPanel.widgets:
                    tw.addTiddler(widget.passage)
                dest = codecs.open(path, 'w', 'utf-8-sig', 'replace')
                order = map(lambda w: w.passage.title,
                            self.storyPanel.sortedWidgets())
                dest.write(tw.toTwee(order))
                dest.close()
            except:
                self.app.displayError('exporting your source code')

        dialog.Destroy()
Example #11
0
 def rebuild (self, event = None, displayAfter = False):
     """
     Builds an HTML version of the story. Pass whether to open the destination file afterwards.
     """
     try:
         # open destination for writing
         
         dest = open(self.buildDestination, 'w')
 
         # assemble our tiddlywiki and write it out
         
         tw = TiddlyWiki()
         
         for widget in self.storyPanel.widgets:
             tw.addTiddler(widget.passage)
         
         dest.write(tw.toHtml(self.app, self.target).encode('utf-8'))
         dest.close()        
         if displayAfter: self.viewBuild()
     except:
         self.app.displayError('building your story')
Example #12
0
    def importSource(self, event=None):
        """Asks the user to choose a file to import source from, then imports into the current story."""
        dialog = wx.FileDialog(
            self,
            "Import Source Code",
            os.getcwd(),
            "",
            "Text Files (*.txt)|*.txt|Twee Source Code (*.tw)|*.tw",
            wx.OPEN | wx.FD_CHANGE_DIR,
        )

        if dialog.ShowModal() == wx.ID_OK:
            try:
                # have a TiddlyWiki object parse it for us

                source = open(dialog.GetPath(), "rb")
                tw = TiddlyWiki()
                tw.addTwee(source.read())
                source.close()

                # add passages for each of the tiddlers the TiddlyWiki saw

                if len(tw.tiddlers):
                    for t in tw.tiddlers:
                        tiddler = tw.tiddlers[t]
                        new = self.storyPanel.newWidget(title=tiddler.title, text=tiddler.text, quietly=True)
                        new.tags = tiddler.tags
                    self.setDirty(True, "Import")
                else:
                    dialog = wx.MessageDialog(
                        self,
                        "No passages were found in this file. Make sure " + "this is a Twee source file.",
                        "No Passages Found",
                        wx.ICON_INFO | wx.OK,
                    )
                    dialog.ShowModal()
            except:
                self.app.displayError("importing your source code")
Example #13
0
    def rebuild (self, event = None, displayAfter = False):
        """
        Builds an HTML version of the story. Pass whether to open the destination file afterwards.
        """        
        try:
            # Remember current working dir and set to savefile's dir. InterTwine StoryIncludes are relative to the Twine file.
            cwd = os.getcwd()
            if self.saveDestination == '':
                twinedocdir = cwd
            else:
                twinedocdir = os.path.dirname(self.saveDestination)
                os.chdir(twinedocdir)
    
            # assemble our tiddlywiki and write it out
            hasstartpassage = False
            tw = TiddlyWiki()
            for widget in self.storyPanel.widgets:
                if widget.passage.title != 'StoryIncludes' and \
                not any(t.startswith('Twine.') for t in widget.passage.tags):
                    widget.passage.pos = widget.pos
                    tw.addTiddler(widget.passage)
                    if widget.passage.title == "Start":
                        hasstartpassage = True

            # is there a Start passage?
            if hasstartpassage == False:
                self.app.displayError('building your story because there is no "Start" passage. ' + "\n" 
                                      + 'Your story will build but the web browser will not be able to run the story. ' + "\n"
                                      + 'Please add a passage with the title "Start"')

            for widget in self.storyPanel.widgets:
                if widget.passage.title == 'StoryIncludes':
                    lines = widget.passage.text.splitlines()
                    lines.append('');
                    # State 0: Look for a filename
                    ## State 1: have filename, look for filename, EXCEPT, INCLUDE, ALIAS
                    ## State 2: EXCEPT mode, look for INCLUDE 3, ALIAS 4 or blank line 0
                    ## State 3: INCLUDE mode, look for EXCEPT 2, ALIAS 4 or blank line 0
                    ## State 4: ALIAS mode, look for EXCEPT 2, INCLUDE 2 or blank line 0
                    state = 0;
                    state_filename = '';
                    excludepassages = TiddlyWiki.INFO_PASSAGES + ['Start']
                    for line in lines:
                        if state == 0:
                            state_filename = line
                            state = 1
                            continue
                        elif state == 1:
                            try:
                                if state_filename.strip() != '':
                                    extension = os.path.splitext(state_filename)[1] 
                                    if extension == '.tws':
                                        if any(state_filename.startswith(t) for t in ['http://', 'https://', 'ftp://']):
                                            openedFile = urllib.urlopen(state_filename)
                                        else:
                                            openedFile = open(state_filename, 'r')
                                        s = StoryFrame(None, app = self.app, state = pickle.load(openedFile))
                                        openedFile.close()
                                        for widget in s.storyPanel.widgets:
                                            if not any(widget.passage.title in t for t in excludepassages) and \
                                            not any('Twine.private' in t for t in widget.passage.tags) and \
                                            not any('Twine.system' in t for t in widget.passage.tags):
                                                tw.addTiddler(widget.passage)
                                        s.Destroy()
                                    elif extension == '.tw' or extension == '.txt' or extension == '.twee':
                                        if any(state_filename.startswith(t) for t in ['http://', 'https://', 'ftp://']):
                                            openedFile = urllib.urlopen(state_filename)
                                            s = openedFile.read()
                                            openedFile.close()
                                            t = tempfile.NamedTemporaryFile(delete=False)
                                            cleanuptempfile = True
                                            t.write(s)
                                            t.close()
                                            filename = t.name
                                        else:
                                            filename = state_filename
                                            cleanuptempfile = False
                                            
                                        tw1 = TiddlyWiki()
                                        tw1.addTweeFromFilename(filename)
                                        if cleanuptempfile: os.remove(filename)
                                        tiddlerkeys = tw1.tiddlers.keys()
                                        for tiddlerkey in tiddlerkeys:
                                            passage = tw1.tiddlers[tiddlerkey]
                                            if not any(passage.title == t for t in excludepassages) and \
                                            not any('Twine.private' in t for t in passage.tags) and \
                                            not any('Twine.system' in t for t in passage.tags):
                                                tw.addTiddler(passage)
                                    else:
                                        raise 'File format not recognized'
                            except:
                                self.app.displayError('opening the Twine file named ' + state_filename + ' which is referred to by the passage StoryIncludes')
                            state_filename = line
                            state = 1
                            continue
                    break
            
            # Decode story settings
            for widget in self.storyPanel.widgets:
                if widget.passage.title == 'StorySettings':
                    lines = widget.passage.text.splitlines()
                    for line in lines:
                        try:
                            (skey,svalue) = line.split(':')
                            tw.storysettings[skey.strip().lower()] = svalue.strip().lower()
                        except:
                            tw.storysettings[line.strip().lower()] = "true"
                    break
            
            # Write the output file
            os.chdir(os.path.dirname(self.buildDestination))
            dest = open(self.buildDestination, 'w')
            dest.write(tw.toHtml(self.app, self.target).encode('utf-8'))
            dest.close()
            os.chdir(cwd)
            if displayAfter: self.viewBuild()
        except:
            self.app.displayError('building your story')
Example #14
0
def main (argv):

	# defaults

	author = 'twee'
	target = 'jonah'
	merge = rss_output = ''
	plugins = []

	# read command line switches

	try:
		opts, args = getopt.getopt(argv, 'a:m:p:r:t:', ['author=', 'merge=', 'plugins=', 'rss=', 'target='])
	except getopt.GetoptError:
		usage()
		sys.exit(2)

	for opt, arg in opts:
		if (opt in ('-a', '--author')):
			author = arg
		elif (opt in ('-m', '--merge')):
			merge = arg
		elif (opt in ('-p', '--plugins')):
			plugins = arg.split(',')
		elif (opt in ('-r', '--rss')):
			rss_output = arg
		elif (opt in ('-t', '--target')):
			target = arg

	# construct a TW object

	tw = TiddlyWiki(author)

	# read in a file to be merged

	if merge != '':
		file = open(merge)
		tw.addHtml(file.read())
		file.close()

	# read source files

	sources = []

	for arg in args:
		for file in glob.glob(arg):
			sources.append(file)

	if len(sources) == 0:
		print 'twee: no source files specified\n'
		sys.exit(2)

	for source in sources:
		file = open(source)
		tw.addTwee(file.read())
		file.close()

	# generate RSS if requested

	if rss_output != '':
		rss_file = open(rss_output, 'w')
		tw.toRss().write_xml(rss_file)
		rss_file.close()

	# output the target header

#	if (target != 'none') and (target != 'plugin'):
#		file = open(scriptPath + os.sep + 'targets' + os.sep + target \
#								+ os.sep + 'header.html')
#		print(file.read())
#		file.close()

	# the tiddlers

	print TwParser(tw)
Example #15
0
    def rebuild(self, event=None, displayAfter=False):
        """
        Builds an HTML version of the story. Pass whether to open the destination file afterwards.
        """
        try:
            # Remember current working dir and set to savefile's dir. InterTwine StoryIncludes are relative to the Twine file.
            cwd = os.getcwd()
            if self.saveDestination == '':
                twinedocdir = cwd
            else:
                twinedocdir = os.path.dirname(self.saveDestination)
                os.chdir(twinedocdir)
            if not self.storyPanel.findWidget('StoryIncludePassages'):
                self.storyPanel.newWidget(title='StoryIncludePassages',
                                          pos=(-1000, -1000),
                                          quietly=True)
                self.storyPanel.findWidget(
                    'StoryIncludePassages').passage.tags.append('Twine.hide')
                self.storyPanel.findWidget(
                    'StoryIncludePassages').passage.tags.append('Twine.system')
                self.storyPanel.findWidget('StoryIncludePassages').pos = [
                    -1000, -1000
                ]
            else:
                self.storyPanel.findWidget(
                    'StoryIncludePassages').passage.tags[:] = ['Twine.hide']
                self.storyPanel.findWidget(
                    'StoryIncludePassages').passage.tags.append('Twine.system')
                self.storyPanel.findWidget('StoryIncludePassages').pos = [
                    -1000, -1000
                ]
            # assemble our tiddlywiki and write it out
            hasstartpassage = False
            tw = TiddlyWiki()
            for widget in self.storyPanel.widgets:
                # if widget.passage.title != 'StoryIncludes' and \
                # not any('Twine.private' in t for t in widget.passage.tags) and \
                # not any('Twine.system' in t for t in widget.passage.tags):
                if widget.passage.title != 'StoryIncludes' and \
                not any(t.startswith('Twine.') for t in widget.passage.tags):
                    tw.addTiddler(widget.passage)
                    if widget.passage.title == "Start":
                        hasstartpassage = True

            # is there a Start passage?
            if hasstartpassage == False:
                self.app.displayError(
                    'building your story because there is no "Start" passage. '
                    + "\n" +
                    'Your story will build but the web-browser will not be able to run the story. '
                    + "\n" + 'Please add a passage with the title "Start"')

            for widget in self.storyPanel.widgets:
                if widget.passage.title == 'StoryIncludes':
                    lines = widget.passage.text.splitlines()
                    lines.append('')
                    # State 0: Look for a filename
                    ## State 1: have filename, look for filename, EXCEPT, INCLUDE, ALIAS
                    ## State 2: EXCEPT mode, look for INCLUDE 3, ALIAS 4 or blank line 0
                    ## State 3: INCLUDE mode, look for EXCEPT 2, ALIAS 4 or blank line 0
                    ## State 4: ALIAS mode, look for EXCEPT 2, INCLUDE 2 or blank line 0
                    state = 0
                    state_filename = ''
                    excludepassages = [
                        'Start', 'StoryMenu', 'StoryTitle', 'StoryAuthor',
                        'StorySubtitle', 'StoryIncludes', 'StorySettings'
                    ]
                    for line in lines:
                        if state == 0:
                            state_filename = line
                            state = 1
                            continue
                        elif state == 1:
                            try:
                                if state_filename.strip() != '':
                                    extension = os.path.splitext(
                                        state_filename)[1]
                                    if extension == '.tws':
                                        if any(
                                                state_filename.startswith(t)
                                                for t in
                                            ['http://', 'https://', 'ftp://']):
                                            openedFile = urllib.urlopen(
                                                state_filename)
                                        else:
                                            openedFile = open(
                                                state_filename, 'r')
                                        s = StoryFrame(
                                            None,
                                            app=self.app,
                                            state=pickle.load(openedFile))
                                        openedFile.close()
                                        for widget in s.storyPanel.widgets:
                                            if not any(widget.passage.title in t for t in excludepassages) and \
                                            not any('Twine.private' in t for t in widget.passage.tags) and \
                                            not any('Twine.system' in t for t in widget.passage.tags):
                                                tw.addTiddler(widget.passage)
                                                if self.storyPanel.findWidget(
                                                        'StoryIncludePassages'
                                                ):
                                                    self.storyPanel.findWidget(
                                                        'StoryIncludePassages'
                                                    ).passage.tags.append(
                                                        widget.passage.title)
                                        s.Destroy()
                                    elif extension == '.tw' or extension == '.txt' or extension == '.twee':
                                        if any(
                                                state_filename.startswith(t)
                                                for t in
                                            ['http://', 'https://', 'ftp://']):
                                            openedFile = urllib.urlopen(
                                                state_filename)
                                            s = openedFile.read()
                                            openedFile.close()
                                            t = tempfile.NamedTemporaryFile(
                                                delete=False)
                                            cleanuptempfile = True
                                            t.write(s)
                                            t.close()
                                            filename = t.name
                                        else:
                                            filename = state_filename
                                            cleanuptempfile = False

                                        tw1 = TiddlyWiki()
                                        tw1.addTweeFromFilename(filename)
                                        if cleanuptempfile: os.remove(filename)
                                        tiddlerkeys = tw1.tiddlers.keys()
                                        for tiddlerkey in tiddlerkeys:
                                            passage = tw1.tiddlers[tiddlerkey]
                                            if not any(passage.title == t for t in excludepassages) and \
                                            not any('Twine.private' in t for t in passage.tags) and \
                                            not any('Twine.system' in t for t in passage.tags):
                                                tw.addTiddler(passage)
                                                if self.storyPanel.findWidget(
                                                        'StoryIncludePassages'
                                                ):
                                                    self.storyPanel.findWidget(
                                                        'StoryIncludePassages'
                                                    ).passage.tags.append(
                                                        passage.title)
                                    else:
                                        raise 'File format not recognized'
                            except:
                                self.app.displayError(
                                    'opening the Twine file named ' +
                                    state_filename +
                                    ' which is referred to by the passage StoryIncludes'
                                )
                            state_filename = line
                            state = 1
                            continue
                    break

            # Decode story settings
            for widget in self.storyPanel.widgets:
                if widget.passage.title == 'StorySettings':
                    lines = widget.passage.text.splitlines()
                    for line in lines:
                        (skey, svalue) = line.split(':')
                        tw.storysettings[skey.strip()] = svalue.strip()
                    break

            # Write the output file
            os.chdir(os.path.dirname(self.buildDestination))
            dest = open(self.buildDestination, 'w')
            dest.write(
                tw.toHtml(self.app, self.target,
                          savePath=self.saveDestination).encode('utf-8'))
            dest.close()
            os.chdir(cwd)
            if displayAfter: self.viewBuild()
        except:
            self.app.displayError('building your story')
Example #16
0
from tiddlywiki import TiddlyWiki

tw5 = TiddlyWiki.parse_from_html('./example/tw5.html')

predicate = lambda t: 'journal' in t.tags
journal_tiddlers = list(tw5.finditer(predicate))

for tiddler in journal_tiddlers:
    tiddler.open_in_browser()

for tiddler in journal_tiddlers:
    tiddler.export_to_file('./example/' + tiddler.title + '.pdf')

tw5.export_to_file('./example/tw5_journal.pdf',
                   '--toc',
                   key=lambda t: t.created,
                   predicates=[predicate])

tw5.open_in_browser(key=lambda t: t.created,
                    predicates=[predicate])
Example #17
0
def main(argv):

    parser = argparse.ArgumentParser(
        description="Convert twee source code into SAM source code")
    parser.add_argument("-a", "--author", default="twee")
    parser.add_argument("-m", "--merge", default="")
    parser.add_argument("-p", "--plugins", nargs="*", default=[])
    parser.add_argument("-r", "--rss", default="")
    parser.add_argument("-t", "--target", default="jonah")
    parser.add_argument("sources")
    parser.add_argument("destination")
    opts = parser.parse_args()

    # construct a TW object

    tw = TiddlyWiki(opts.author)

    # read in a file to be merged

    if opts.merge:
        with io.open(opts.merge, encoding="utf-8-sig") as f:
            tw.addHtml(f.read())

    # read source files

    sources = glob.glob(opts.sources)

    if not sources:
        logging.error('twee2sam: no source files specified\n')
        sys.exit(2)

    for source in sources:
        with io.open(source, encoding="utf-8-sig") as f:
            tw.addTwee(f.read())

    src_dir = os.path.dirname(sources[0])

    #
    # Parse the file
    #

    twp = TwParser(tw)

    #
    # Number the passages
    #

    passage_indexes = {}

    def process_passage_index(passage):
        global next_seq

        if not passage.title in passage_indexes:
            passage_indexes[passage.title] = process_passage_index.next_seq
            process_passage_index.next_seq += 1

    process_passage_index.next_seq = 0

    # 'Start' _must_ be the first script
    if not 'Start' in twp.passages:
        logging.error('twee2sam: "Start" passage not found.\n')
        sys.exit(2)

    process_passage_index(twp.passages['Start'])
    for passage in twp.passages.values():
        process_passage_index(passage)

    #
    # Generate the file list
    #
    passage_order = [
        psg for psg, idx in sorted(passage_indexes.items(), key=itemgetter(1))
    ]

    def name_to_identifier(s):
        return re.sub(r'[^0-9A-Za-z]', '_', s)

    def script_name(s):
        return name_to_identifier(s) + '.twsam'

    if not os.path.exists(opts.destination):
        os.makedirs(opts.destination)
    with io.open(os.path.join(opts.destination, 'Script.list.txt'),
                 'w',
                 encoding="utf-8") as f_list:
        for passage_name in passage_order:
            passage = twp.passages[passage_name]
            f_list.write(u"%s" % script_name(passage.title))
            f_list.write(u'\n')

    #
    # Generate SAM scripts
    #

    # A is used as a temp var for menu selection
    # B is used as a temp var for menu selection
    # C and above are available
    variables = VariableFactory(2)

    image_list = []
    music_list = []
    for passage in twp.passages.values():
        with io.open(os.path.join(opts.destination,
                                  script_name(passage.title)),
                     'w',
                     encoding="utf-8") as script:

            def check_print():
                if check_print.pending:
                    script.write(u'!\n')
                    check_print.in_buffer = 0
                    check_print.pending = False

            check_print.pending = False
            check_print.in_buffer = 0

            def warning(msg):
                logging.warning("Warning on \'{0}\': {1}".format(
                    passage.title, msg))

            def out_string(msg):
                MAX_LEN = 512
                # go through the string and replace characters
                msg = ''.join(
                    map(
                        lambda x: {
                            '"': "'",
                            '[': '{',
                            ']': '}'
                        }[x] if x in ('"', '[', '{') else x, msg))
                msg_len = len(msg)

                # Checks for buffer overflow
                if check_print.in_buffer + msg_len > MAX_LEN - 1:
                    warning(
                        "The text exceeds the maximum buffer size; try to intersperse the text with some <<pause>> macros"
                    )
                    remaining = max(0, MAX_LEN - 1 - check_print.in_buffer)
                    msg = msg[:remaining]

                script.write(u'"{0}"'.format(msg))
                script.write(u'\n')

                check_print.in_buffer += len(msg)

            def out_set(cmd):
                out_expr(cmd.expr)
                script.write(u' ')
                target = variables.set_var(cmd.target)
                script.write(u"%s\n" % target)

            def out_if(cmd):
                out_expr(cmd.expr)
                script.write(u'[\n')
                process_command_list(cmd.children, True)
                script.write(u' 0]\n')

            def out_print(cmd):
                # print a numeric qvariable
                out_expr(cmd.expr)
                script.write(u'"\#"')

            def out_expr(expr):
                def var_locator(name):
                    return variables.get_var(name).replace(':', '')

                generated = twexpression.to_sam(expr, var_locator=var_locator)
                script.write(u"%s" % generated)

            def out_call(cmd):
                call_target = None
                for k in passage_indexes.keys():
                    if cmd.target == k:
                        call_target = passage_indexes[k]
                if call_target:
                    script.write(u"%s" % call_target)
                    script.write(u'c\n')

            def out_jump(cmd):
                call_target = None
                for k in passage_indexes.keys():
                    if cmd.target == k:
                        call_target = passage_indexes[k]
                if call_target:
                    script.write(u"%s" % call_target)
                    script.write(u'j\n')

# Outputs all the text

            links = []

            def register_link(cmd, is_conditional):
                temp_var = variables.new_temp_var() if is_conditional else None
                links.append((cmd, temp_var))
                if temp_var:
                    script.write(u'1%s' % variables.set_var(temp_var))

            def process_command_list(commands, is_conditional=False):
                for cmd in commands:
                    if cmd.kind == 'text':
                        text = cmd.text.strip()
                        if text:
                            out_string(cmd.text)
                            check_print.pending = True
                    elif cmd.kind == 'print':
                        out_print(cmd)
                    elif cmd.kind == 'image':
                        check_print()
                        if not cmd.path in image_list:
                            image_list.append(cmd.path)
                        script.write(u'{0}i\n'.format(
                            image_list.index(cmd.path)))
                    elif cmd.kind == 'link':
                        register_link(cmd, is_conditional)
                        out_string(cmd.actual_label())
                    elif cmd.kind == 'list':
                        for lcmd in cmd.children:
                            if lcmd.kind == 'link':
                                register_link(lcmd, is_conditional)
                    elif cmd.kind == 'pause':
                        check_print.pending = True
                        check_print()
                    elif cmd.kind == 'set':
                        out_set(cmd)
                    elif cmd.kind == 'if':
                        out_if(cmd)
                    elif cmd.kind == 'call':
                        out_call(cmd)
                    elif cmd.kind == 'jump':
                        out_jump(cmd)
                    elif cmd.kind == 'return':
                        script.write(u'$\n')
                    elif cmd.kind == 'music':
                        if not cmd.path in music_list:
                            music_list.append(cmd.path)
                        script.write(u'{0}m\n'.format(
                            music_list.index(cmd.path)))
                    elif cmd.kind == 'display':
                        try:
                            target = twp.passages[cmd.target]
                        except KeyError:
                            logging.error(
                                "Display macro target passage {0} not found!".
                                format(cmd.target),
                                file=sys.stderr)
                            return
                        process_command_list(target.commands)

            process_command_list(passage.commands)

            check_print()

            # Builds the menu from the links

            if links:
                # Outputs the options separated by line breaks, max 28 chars per line
                for link, temp_var in links:
                    if temp_var:
                        script.write(u'{0}['.format(
                            variables.get_var(temp_var)))

                    out_string(link.actual_label()[:28] + '\n')

                    if temp_var:
                        script.write(u'0]\n')

                script.write(u'?A.\n')
                check_print.in_buffer = 0

                # Outputs the menu destinations
                script.write(u'0B.\n')

                for link, temp_var in links:
                    if temp_var:
                        script.write(u'{0}['.format(
                            variables.get_var(temp_var)))

                    if not link.target in passage_indexes:
                        # TODO: Create a better exception
                        raise BaseException(
                            'Link points to a nonexisting passage: "{0}"'.
                            format(link.target))

                    script.write(u'A:B:=[{0}j]'.format(
                        passage_indexes[link.target]))
                    script.write(u'B:1+B.\n')

                    if temp_var:
                        script.write(u'0]\n')

            else:
                # No links? Generates an infinite loop.
                script.write(u'1[1]\n')

    #
    # Function to copy the files on a list and generate a list file
    #
    def copy_and_build_list(list_file_name,
                            file_list,
                            item_extension,
                            item_suffix='',
                            empty_item='blank'):
        with io.open(os.path.join(opts.destination, list_file_name),
                     'w',
                     encoding="utf-8") as list_file:
            for file_path in file_list:
                item_name = name_to_identifier(
                    os.path.splitext(os.path.basename(file_path))[0])
                list_file.write("%s%s\n" % (item_name, item_suffix))
                shutil.copyfile(
                    os.path.join(src_dir, file_path),
                    os.path.join(opts.destination,
                                 '%s.%s' % (item_name, item_extension)))

            if not file_list:
                list_file.write(u"%s%s\n" % (empty_item, item_suffix))

    #
    # Copy images and builds the image list
    #
    copy_and_build_list('Images.txt', image_list, 'png')

    #
    # Copy music and builds the music list
    #
    copy_and_build_list('Music.list.txt', music_list, 'epsgmod', '.epsgmod',
                        'empty')
Example #18
0
def import_tiddlers(predicate):
    tw5 = TiddlyWiki.parse_from_html('./_wiki/index.html')
    guide_tiddlers = list(tw5.finditer(predicate))

    for tiddler in guide_tiddlers:
        tiddler.export_to_file(source_dir + tiddler.title + '.md')
Example #19
0
def main (argv):

    parser = argparse.ArgumentParser(description="Convert twee source code into SAM source code")
    parser.add_argument("-a", "--author", default="twee")
    parser.add_argument("-m", "--merge", default="")
    parser.add_argument("-p", "--plugins", nargs="*", default=[])
    parser.add_argument("-r", "--rss", default="")
    parser.add_argument("-t", "--target", default="jonah")
    parser.add_argument("sources")
    parser.add_argument("destination")
    opts = parser.parse_args()

    # construct a TW object

    tw = TiddlyWiki(opts.author)

    # read in a file to be merged

    if opts.merge:
        with io.open(opts.merge, encoding="utf-8-sig") as f:
            tw.addHtml(f.read())

    # read source files

    sources = glob.glob(opts.sources)

    if not sources:
        logging.error('twee2sam: no source files specified\n')
        sys.exit(2)

    for source in sources:
        with io.open(source, encoding="utf-8-sig") as f:
            tw.addTwee(f.read())

    src_dir = os.path.dirname(sources[0])

    #
    # Parse the file
    #

    twp = TwParser(tw)


    #
    # Number the passages
    #

    passage_indexes = {}

    def process_passage_index(passage):
        global next_seq

        if not passage.title in passage_indexes:
            passage_indexes[passage.title] = process_passage_index.next_seq
            process_passage_index.next_seq += 1

    process_passage_index.next_seq = 0

    # 'Start' _must_ be the first script
    if not 'Start' in twp.passages:
        logging.error('twee2sam: "Start" passage not found.\n')
        sys.exit(2)

    process_passage_index(twp.passages['Start'])
    for passage in twp.passages.values():
        process_passage_index(passage)

    #
    # Generate the file list
    #
    passage_order = [psg for psg, idx in sorted(passage_indexes.items(), key=itemgetter(1))]


    def name_to_identifier(s):
        return re.sub(r'[^0-9A-Za-z]', '_', s)

    def script_name(s):
        return name_to_identifier(s) + '.twsam'

    if not os.path.exists(opts.destination):
        os.makedirs(opts.destination)
    with io.open(os.path.join(opts.destination, 'Script.list.txt'), 'w', encoding="utf-8") as f_list:
        for passage_name in passage_order:
            passage = twp.passages[passage_name]
            f_list.write(u"%s" % script_name(passage.title))
            f_list.write(u'\n')


    #
    # Generate SAM scripts
    #

    # A is used as a temp var for menu selection
    # B is used as a temp var for menu selection
    # C and above are available
    variables = VariableFactory(2)

    image_list = []
    music_list = []
    for passage in twp.passages.values():
        with io.open(os.path.join(opts.destination, script_name(passage.title)), 'w', encoding="utf-8") as script:

            def check_print():
                if check_print.pending:
                    script.write(u'!\n')
                    check_print.in_buffer = 0
                    check_print.pending = False

            check_print.pending = False
            check_print.in_buffer = 0

            def warning(msg):
                logging.warning("Warning on \'{0}\': {1}".format(passage.title, msg))

            def out_string(msg):
                MAX_LEN = 512
                # go through the string and replace characters
                msg = ''.join(map(lambda x: {'"': "'", '[': '{', ']':'}'}[x] if x in ('"','[','{') else x, msg))
                msg_len = len(msg)

                # Checks for buffer overflow
                if check_print.in_buffer + msg_len > MAX_LEN - 1:
                    warning("The text exceeds the maximum buffer size; try to intersperse the text with some <<pause>> macros")
                    remaining = max(0, MAX_LEN - 1 -  check_print.in_buffer)
                    msg = msg[:remaining]

                script.write(u'"{0}"'.format(msg))
                script.write(u'\n')

                check_print.in_buffer += len(msg)

            def out_set(cmd):
                out_expr(cmd.expr)
                script.write(u' ')
                target = variables.set_var(cmd.target)
                script.write(u"%s\n" % target)

            def out_if(cmd):
                out_expr(cmd.expr)
                script.write(u'[\n')
                process_command_list(cmd.children, True)
                script.write(u' 0]\n')

            def out_print(cmd):
                # print a numeric qvariable
                out_expr(cmd.expr)
                script.write(u'"\#"')

            def out_expr(expr):
                def var_locator(name):
                    return variables.get_var(name).replace(':', '')
                generated = twexpression.to_sam(expr, var_locator = var_locator)
                script.write(u"%s" % generated)

            def out_call(cmd):
                call_target = None
                for k in passage_indexes.keys():
                    if cmd.target == k:
                        call_target = passage_indexes[k]
                if call_target:
                    script.write(u"%s" % call_target)
                    script.write(u'c\n')

            # Outputs all the text

            links = []

            def register_link(cmd, is_conditional):
                temp_var = variables.new_temp_var() if is_conditional else None
                links.append((cmd, temp_var))
                if temp_var:
                    script.write(u'1%s' % variables.set_var(temp_var))

            def process_command_list(commands, is_conditional=False):
                for cmd in commands:
                    if cmd.kind == 'text':
                        text = cmd.text.strip()
                        if text:
                            out_string(text)
                            check_print.pending = True
                    elif cmd.kind == 'print':
                        out_print(cmd)
                    elif cmd.kind == 'image':
                        check_print()
                        if not cmd.path in image_list:
                            image_list.append(cmd.path)
                        script.write(u'{0}i\n'.format(image_list.index(cmd.path)))
                    elif cmd.kind == 'link':
                        register_link(cmd, is_conditional)
                        out_string(cmd.actual_label())
                    elif cmd.kind == 'list':
                        for lcmd in cmd.children:
                            if lcmd.kind == 'link':
                                register_link(lcmd, is_conditional)
                    elif cmd.kind == 'pause':
                        check_print.pending = True
                        check_print()
                    elif cmd.kind == 'set':
                        out_set(cmd)
                    elif cmd.kind == 'if':
                        out_if(cmd)
                    elif cmd.kind == 'call':
                        out_call(cmd)
                    elif cmd.kind == 'return':
                        script.write(u'$\n')
                    elif cmd.kind == 'music':
                        if not cmd.path in music_list:
                            music_list.append(cmd.path)
                        script.write(u'{0}m\n'.format(music_list.index(cmd.path)))
                    elif cmd.kind == 'display':
                        try:
                            target = twp.passages[cmd.target]
                        except KeyError:
                            logging.error("Display macro target passage {0} not found!".format(cmd.target), file=sys.stderr)
                            return
                        process_command_list(target.commands)

            process_command_list(passage.commands)

            check_print()

            # Builds the menu from the links

            if links:
                # Outputs the options separated by line breaks, max 28 chars per line
                for link, temp_var in links:
                    if temp_var:
                        script.write(u'{0}['.format(variables.get_var(temp_var)))

                    out_string(link.actual_label()[:28] + '\n')

                    if temp_var:
                        script.write(u'0]\n')

                script.write(u'?A.\n')
                check_print.in_buffer = 0

                # Outputs the menu destinations
                script.write(u'0B.\n');

                for link, temp_var in links:
                    if temp_var:
                        script.write(u'{0}['.format(variables.get_var(temp_var)))

                    if not link.target in passage_indexes:
                        # TODO: Create a better exception
                        raise BaseException('Link points to a nonexisting passage: "{0}"'.format(link.target))

                    script.write(u'A:B:=[{0}j]'.format(passage_indexes[link.target]))
                    script.write(u'B:1+B.\n')

                    if temp_var:
                        script.write(u'0]\n')

            else:
                # No links? Generates an infinite loop.
                script.write(u'1[1]\n')



    #
    # Function to copy the files on a list and generate a list file
    #
    def copy_and_build_list(list_file_name, file_list, item_extension, item_suffix = '', empty_item = 'blank'):
        with io.open(os.path.join(opts.destination, list_file_name), 'w', encoding="utf-8") as list_file:
            for file_path in file_list:
                item_name = name_to_identifier(os.path.splitext(os.path.basename(file_path))[0])
                list_file.write("%s%s\n" % (item_name, item_suffix))
                shutil.copyfile(os.path.join(src_dir, file_path), os.path.join(opts.destination, '%s.%s' % (item_name, item_extension)))

            if not file_list:
                list_file.write(u"%s%s\n" % (empty_item, item_suffix))



    #
    # Copy images and builds the image list
    #
    copy_and_build_list('Images.txt', image_list, 'png')



    #
    # Copy music and builds the music list
    #
    copy_and_build_list('Music.list.txt', music_list, 'epsgmod', '.epsgmod', 'empty')