def sort_projects(<EOL>self,<EOL>workflowTags):
self.refresh<EOL>if not isinstance(workflowTags, list):<EOL><INDENT>workflowTagsLists = workflowTags.strip().replace("<STR_LIT:U+002C>", "<STR_LIT>").replace("<STR_LIT:@>", "<STR_LIT>")<EOL>workflowTagsLists = workflowTagsLists.split("<STR_LIT:U+0020>")<EOL><DEDENT>else:<EOL><INDENT>workflowTagsLists = []<EOL>workflowTagsLists[:] = [l.replace("<STR_LIT:@>", "<STR_LIT>") for l in workflowTags]<EOL><DEDENT>matchedProjects = collections.OrderedDict()<EOL>unmatchedProjects = []<EOL>for wt in workflowTagsLists:<EOL><INDENT>matchedProjects[wt.lower()] = []<EOL><DEDENT>for p in self.projects:<EOL><INDENT>matched = False<EOL>for pt in p.tags:<EOL><INDENT>if matched:<EOL><INDENT>break<EOL><DEDENT>for wt in workflowTagsLists:<EOL><INDENT>thisTag = pt.lower()<EOL>if "<STR_LIT:(>" not in wt:<EOL><INDENT>thisTag = pt.split("<STR_LIT:(>")[<NUM_LIT:0>].lower()<EOL><DEDENT>if thisTag == wt.lower() and matched == False:<EOL><INDENT>matchedProjects[wt.lower()].append(p)<EOL>matched = True<EOL>break<EOL><DEDENT><DEDENT><DEDENT>if matched == False:<EOL><INDENT>unmatchedProjects.append(p)<EOL><DEDENT><DEDENT>sortedProjects = []<EOL>for k, v in matchedProjects.iteritems():<EOL><INDENT>sortedProjects += v<EOL><DEDENT>sortedProjects += unmatchedProjects<EOL>self.projects = sortedProjects<EOL>self.content = self.to_string(<EOL>title=False, projects=sortedProjects, indentLevel=<NUM_LIT:0>)<EOL>for p in self.projects:<EOL><INDENT>p.projects = p.sort_projects(workflowTags)<EOL><DEDENT>oldContent = self.to_string(indentLevel=<NUM_LIT:1>)<EOL>newContent = self.to_string(<EOL>indentLevel=<NUM_LIT:1>, projects=sortedProjects)<EOL>if self.parent:<EOL><INDENT>self.parent._update_document_tree(<EOL>oldContent=oldContent,<EOL>newContent=newContent<EOL>)<EOL><DEDENT>self.content = self.content.replace(self.to_string(indentLevel=<NUM_LIT:0>, title=False), self.to_string(<EOL>indentLevel=<NUM_LIT:0>, title=False, projects=sortedProjects))<EOL>self.refresh<EOL>return sortedProjects<EOL>
*order the projects within this taskpaper object via a list of tags*

         The order of the tags in the list dictates the order of the sort - first comes first*

        **Key Arguments:**
            - ``workflowTags`` -- a string of space/comma seperated tags.

        **Return:**
            - ``None``

        **Usage:**

            To recursively sort the projects within a taskpaper document with the following order:

            1. *@due*
            2. *@flag*
            3. *@hold*
            4. *@next*
            5. *@someday*
            6. *@wait*

            use the following:

            .. code-block:: python

                doc.sort_projects("@due, @flag, @hold, @next, @someday, @wait")