def get_ext(self, c, p, ext):
     '''Return the file extension to be used in the temp file.'''
     trace = False and not g.unitTesting
     if trace: g.trace(ext)
     if ext:
         for ch in ("'", '"'):
             if ext.startswith(ch): ext = ext.strip(ch)
     if not ext:
         # if node is part of @<file> tree, get ext from file name
         for p2 in p.self_and_parents():
             if p2.isAnyAtFileNode():
                 fn = p2.h.split(None, 1)[1]
                 ext = g.os_path_splitext(fn)[1]
                 if trace: g.trace('found node:', ext, p2.h)
                 break
     if not ext:
         theDict = c.scanAllDirectives()
         language = theDict.get('language')
         ext = g.app.language_extension_dict.get(language)
         if trace: g.trace('found directive', language, ext)
     if not ext:
         ext = '.txt'
         if trace: g.trace('use default (.txt)')
     if ext[0] != '.':
         ext = '.' + ext
     if trace: g.trace(ext)
     return ext
Beispiel #2
0
    def files_in_dir(self, theDir, recursive=True, extList=None, excludeDirs=None):
        """
        Return a list of all Python files in the directory.
        Include all descendants if recursiveFlag is True.
        Include all file types if extList is None.
        """
        import glob
        import os

        # if extList is None: extList = ['.py']
        if excludeDirs is None:
            excludeDirs = []
        result = []
        if recursive:
            for root, dirs, files in os.walk(theDir):
                for z in files:
                    fn = g.os_path_finalize_join(root, z)
                    junk, ext = g.os_path_splitext(fn)
                    if not extList or ext in extList:
                        result.append(fn)
                if excludeDirs and dirs:
                    for z in dirs:
                        if z in excludeDirs:
                            dirs.remove(z)
        else:
            for ext in extList:
                result.extend(glob.glob("%s.*%s" % (theDir, ext)))
        return sorted(list(set(result)))
 def clean_file_name(self, c, ext, p):
     '''Compute the file name when subdirectories mirror the node's hierarchy in Leo.'''
     trace = False and not g.unitTesting
     use_extentions = c.config.getBool('open_with_uses_derived_file_extensions')
     ancestors, found = [], False
     for p2 in p.self_and_parents():
         h = p2.anyAtFileNodeName()
         if not h:
             h = p2.h # Not an @file node: use the entire header
         elif use_extentions and not found:
             # Found the nearest ancestor @<file> node.
             found = True
             base, ext2 = g.os_path_splitext(h)
             if p2 == p: h = base
             if ext2: ext = ext2
         ancestors.append(g.sanitize_filename(h))
     # The base directory is <tempdir>/Leo<id(v)>.
     ancestors.append("Leo" + str(id(p.v)))
     # Build temporary directories.
     td = os.path.abspath(tempfile.gettempdir())
     while len(ancestors) > 1:
         td = os.path.join(td, ancestors.pop())
         if not os.path.exists(td):
             # if trace: g.trace('creating',td)
             os.mkdir(td)
     # Compute the full path.
     name = ancestors.pop() + ext
     path = os.path.join(td, name)
     if trace: g.trace(path)
     return path
Beispiel #4
0
 def completeFileName(self, fileName):
     g = self.g
     if not (fileName and fileName.strip()): return ''
     import os
     fileName = g.os_path_finalize_join(os.getcwd(), fileName)
     head, ext = g.os_path_splitext(fileName)
     if not ext: fileName = fileName + ".leo"
     return fileName
Beispiel #5
0
 def callback (event,c=c,p=p):
     path, name = g.os_path_split(p.filename)
     name, ext = g.os_path_splitext(name)
     pc = g.app.pluginsController
     if pc and pc.isLoaded(name):
         p.hastoplevel(c)
     else:
         p.about()
Beispiel #6
0
 def markerFromFileName(self, filename):
     '''Return the sentinel delimiter comment to be used for filename.'''
     x = self
     if not filename: return None
     root, ext = g.os_path_splitext(filename)
     if ext == '.tmp':
         root, ext = os.path.splitext(root)
     delims = g.comment_delims_from_extension(filename)
     marker = x.Marker(delims)
     return marker
Beispiel #7
0
def openFile(c,parent,d, autoload=False):
    """Open an existing file"""

    path = getPath(c, parent)

    if not os.path.isfile(path):
        return

    oversize = os.stat(path).st_size > c.__active_path['max_size']

    if not autoload:
        binary_open = g.os_path_splitext(path)[-1].lower() in (
            c.config.getData('active_path_bin_open') or '')

        if not binary_open:
            start = open(path).read(100)
            for i in start:
                if ord(i) == 0:
                    binary_open = True
                    break

        if binary_open:
            g.es('Treating file as binary')
            g.handleUrl('file://' + path,c=c)
            # if not query(c, "File may be binary, continue?"):
            #     return
            return

        if oversize:
            if not query(c, "File size greater than %d bytes, continue?" %
              c.__active_path['max_size']):
                return

    if autoload and oversize:
        return

    atType = c.config.getString('active_path_attype') or 'auto'
    parent.h = '@' + atType + ' ' + parent.h
    c.selectPosition(parent)
    if atType == 'asis':
        parent.b = open(d).read()
    else:
        c.refreshFromDisk()
    c.bodyWantsFocus()
Beispiel #8
0
 def compute_ext(self, c, p, ext):
     '''Return the file extension to be used in the temp file.'''
     if ext:
         for ch in ("'", '"'):
             if ext.startswith(ch): ext = ext.strip(ch)
     if not ext:
         # if node is part of @<file> tree, get ext from file name
         for p2 in p.self_and_parents(copy=False):
             if p2.isAnyAtFileNode():
                 fn = p2.h.split(None, 1)[1]
                 ext = g.os_path_splitext(fn)[1]
                 break
     if not ext:
         theDict = c.scanAllDirectives()
         language = theDict.get('language')
         ext = g.app.language_extension_dict.get(language)
     if not ext:
         ext = '.txt'
     if ext[0] != '.':
         ext = '.' + ext
     return ext
Beispiel #9
0
def openFile(c,parent,d, autoload=False):
    """Open an existing file"""
    # hdr = os.path.basename(d)
    # parent.h = '@auto '+hdr
    # parent.b = file(d).read()

    path = getPath(c, parent)

    if not os.path.isfile(path):
        return

    if not autoload:
        binary_open = g.os_path_splitext(path)[-1].lower() in (
            c.config.getData('active_path_bin_open') or '')
            
        if not binary_open:
            start = open(path).read(100)
            for i in start:
                if ord(i) == 0:
                    binary_open = True
                    break
                    
        if binary_open:
            g.es('Treating file as binary')
            g.handleUrl('file://' + path,c=c)
            # if not query(c, "File may be binary, continue?"):
            #     return
            return

        if os.stat(path).st_size > c.__active_path['max_size']:
            if not query(c, "File size greater than %d bytes, continue?" %
              c.__active_path['max_size']):
                return

    c.importCommands.createOutline(d,parent=parent,atAuto=True)
    atType = c.config.getString('active_path_attype') or 'auto'
    parent.h = '@' + atType + ' ' + parent.h

    c.bodyWantsFocus()
 def loadTreeHandlers(self):
     """Load all the handler for tree items"""
     #
     # Paths for key folders
     plugin_path = g.os_path_join(g.app.loadDir, "..", "plugins")
     self.handler_path = handler_path = g.os_path_join(g.app.loadDir, "..", "plugins", "trees")
     #
     if not g.os_path_isdir(handler_path):
         g.es("No tree handler folder found", color="red")
     else:
         g.es("Scanning for tree handlers", color="blue")
         #
         # Add folder locations to path
         old_path = sys.path[:]
         sys.path.insert(0, plugin_path)
         sys.path.insert(0, handler_path)
         #@+<< Get plugin manager module >>
         #@+node:ekr.20050329082101.135: *4* << Get plugin manager module >>
         # Get the manager
         try:
             self.plugin_manager = __import__("plugin_manager")
         except ImportError as err:
             g.es("Autotrees did not load plugin manager: %s" % (err,), color="red")
             self.plugin_manager = None
         #@-<< Get plugin manager module >>
         #@+<< Find all handlers >>
         #@+node:ekr.20050329082101.136: *4* << Find all handlers >>
         # Find all handlers
         for filename in glob.glob(g.os_path_join(handler_path, "*.py")):
             handler_name = g.os_path_splitext(g.os_path_split(filename)[1])[0]
             g.es("... looking in %s" % handler_name, color="blue")
             try:
                 self.loadHandlersFrom(handler_name)
             except BadHandler as err:
                 g.es("... unable to load '%s' handler: %s" % (handler_name, err), color="red")
         #@-<< Find all handlers >>
         # Restore
         sys.path = old_path
Beispiel #11
0
 def set_expected_imported_headlines(self,root):
     '''Set v._imported_headline for every vnode.'''
     trace = False and not g.unitTesting
     cc = self
     c = cc.c
     ic = cc.c.importCommands
     language = g.scanForAtLanguage(c,root) 
     ext = '.'+g.app.language_extension_dict.get(language)
     aClass = ic.classDispatchDict.get(ext)
     scanner = aClass(importCommands=ic,atAuto=True)
     # Duplicate the fn logic from ic.createOutline.
     theDir = g.setDefaultDirectory(c,root,importing=True)
     fn = c.os_path_finalize_join(theDir,root.h)
     fn = root.h.replace('\\','/')
     junk,fn = g.os_path_split(fn)
     fn,junk = g.os_path_splitext(fn)
     if aClass and hasattr(scanner,'headlineForNode'):
         for p in root.subtree():
             if not hasattr(p.v,'_imported_headline'):
                 h = scanner.headlineForNode(fn,p)
                 setattr(p.v,'_imported_headline',h)
                 if trace and h != p.h:
                     g.trace('==>',h) # p.h,'==>',h
Beispiel #12
0
def openFile(c, parent, d, autoload=False):
    """Open an existing file"""

    path = getPath(c, parent)

    if not os.path.isfile(path):
        return

    if not autoload:
        binary_open = g.os_path_splitext(path)[-1].lower() in (c.config.getData("active_path_bin_open") or "")

        if not binary_open:
            start = open(path).read(100)
            for i in start:
                if ord(i) == 0:
                    binary_open = True
                    break

        if binary_open:
            g.es("Treating file as binary")
            g.handleUrl("file://" + path, c=c)
            # if not query(c, "File may be binary, continue?"):
            #     return
            return

        if os.stat(path).st_size > c.__active_path["max_size"]:
            if not query(c, "File size greater than %d bytes, continue?" % c.__active_path["max_size"]):
                return

    atType = c.config.getString("active_path_attype") or "auto"
    parent.h = "@" + atType + " " + parent.h
    c.selectPosition(parent)
    if atType == "asis":
        parent.b = open(d).read()
    else:
        c.refreshFromDisk()
    c.bodyWantsFocus()
def importAnyFile(self, event=None):
    '''Import one or more files.'''
    c = self
    ic = c.importCommands
    types = [
        ("All files", "*"),
        ("C/C++ files", "*.c"),
        ("C/C++ files", "*.cpp"),
        ("C/C++ files", "*.h"),
        ("C/C++ files", "*.hpp"),
        ("FreeMind files", "*.mm.html"),
        ("Java files", "*.java"),
        ("JavaScript files", "*.js"),
        # ("JSON files", "*.json"),
        ("Mindjet files", "*.csv"),
        ("MORE files", "*.MORE"),
        ("Lua files", "*.lua"),
        ("Pascal files", "*.pas"),
        ("Python files", "*.py"),
        ("Tabbed files", "*.txt"),
    ]
    names = g.app.gui.runOpenFileDialog(c,
        title="Import File",
        filetypes=types,
        defaultextension=".py",
        multiple=True)
    c.bringToFront()
    if names:
        g.chdir(names[0])
    else:
        names = []
    if not names:
        if g.unitTesting:
            # a kludge for unit testing.
            c.init_error_dialogs()
            c.raise_error_dialogs(kind='read')
        return
    # New in Leo 4.9: choose the type of import based on the extension.
    c.init_error_dialogs()
    derived = [z for z in names if c.looksLikeDerivedFile(z)]
    others = [z for z in names if z not in derived]
    if derived:
        ic.importDerivedFiles(parent=c.p, paths=derived)
    for fn in others:
        junk, ext = g.os_path_splitext(fn)
        if ext.startswith('.'):
            ext = ext[1:]
        if ext == 'csv':
            ic.importMindMap([fn])
        elif ext in ('cw', 'cweb'):
            ic.importWebCommand([fn], "cweb")
        # Not useful. Use @auto x.json instead.
        # elif ext == 'json':
            # ic.importJSON([fn])
        elif fn.endswith('mm.html'):
            ic.importFreeMind([fn])
        elif ext in ('nw', 'noweb'):
            ic.importWebCommand([fn], "noweb")
        elif ext == 'txt':
            ic.importFlattenedOutline([fn])
        else:
            # Make *sure* that parent.b is empty.
            last = c.lastTopLevel()
            parent = last.insertAfter()
            parent.v.h = 'Imported Files'
            ic.importFilesCommand(
                files=[fn],
                parent=parent,
                treeType='@auto', # was '@clean'
                    # Experimental: attempt to use permissive section ref logic.
            )
    c.raise_error_dialogs(kind='read')
Beispiel #14
0
 def compare_directories(self, path1, path2):
     # Ignore everything except the directory name.
     dir1 = g.os_path_dirname(path1)
     dir2 = g.os_path_dirname(path2)
     dir1 = g.os_path_normpath(dir1)
     dir2 = g.os_path_normpath(dir2)
     if dir1 == dir2:
         return self.show("Please pick distinct directories.")
     try:
         list1 = os.listdir(dir1)
     except Exception:
         return self.show("invalid directory:" + dir1)
     try:
         list2 = os.listdir(dir2)
     except Exception:
         return self.show("invalid directory:" + dir2)
     if self.outputFileName:
         self.openOutputFile()
     ok = self.outputFileName is None or self.outputFile
     if not ok: return None
     # Create files and files2, the lists of files to be compared.
     files1 = []
     files2 = []
     for f in list1:
         junk, ext = g.os_path_splitext(f)
         if self.limitToExtension:
             if ext == self.limitToExtension:
                 files1.append(f)
         else:
             files1.append(f)
     for f in list2:
         junk, ext = g.os_path_splitext(f)
         if self.limitToExtension:
             if ext == self.limitToExtension:
                 files2.append(f)
         else:
             files2.append(f)
     # Compare the files and set the yes, no and missing lists.
     yes = []; no = []; missing1 = []; missing2 = []
     for f1 in files1:
         head, f2 = g.os_path_split(f1)
         if f2 in files2:
             try:
                 name1 = g.os_path_join(dir1, f1)
                 name2 = g.os_path_join(dir2, f2)
                 val = filecmp.cmp(name1, name2, 0)
                 if val: yes.append(f1)
                 else: no.append(f1)
             except Exception:
                 self.show("exception in filecmp.cmp")
                 g.es_exception()
                 missing1.append(f1)
         else:
             missing1.append(f1)
     for f2 in files2:
         head, f1 = g.os_path_split(f2)
         if f1 not in files1:
             missing2.append(f1)
     # Print the results.
     for kind, files in (
         ("----- matches --------", yes),
         ("----- mismatches -----", no),
         ("----- not found 1 ------", missing1),
         ("----- not found 2 ------", missing2),
     ):
         self.show(kind)
         for f in files:
             self.show(f)
     if self.outputFile:
         self.outputFile.close()
         self.outputFile = None
     return None # To keep pychecker happy.
def importAnyFile(self, event=None):
    """Import one or more files."""
    c = self
    ic = c.importCommands
    types = [
        ("All files", "*"),
        ("C/C++ files", "*.c"),
        ("C/C++ files", "*.cpp"),
        ("C/C++ files", "*.h"),
        ("C/C++ files", "*.hpp"),
        ("FreeMind files", "*.mm.html"),
        ("Java files", "*.java"),
        ("JavaScript files", "*.js"),
        # ("JSON files", "*.json"),
        ("Mindjet files", "*.csv"),
        ("MORE files", "*.MORE"),
        ("Lua files", "*.lua"),
        ("Pascal files", "*.pas"),
        ("Python files", "*.py"),
        ("Tabbed files", "*.txt"),
    ]
    names = g.app.gui.runOpenFileDialog(c,
        title="Import File",
        filetypes=types,
        defaultextension=".py",
        multiple=True)
    c.bringToFront()
    if names:
        g.chdir(names[0])
    else:
        names = []
    if not names:
        if g.unitTesting:
            # a kludge for unit testing.
            c.init_error_dialogs()
            c.raise_error_dialogs(kind='read')
        return
    # New in Leo 4.9: choose the type of import based on the extension.
    c.init_error_dialogs()
    derived = [z for z in names if c.looksLikeDerivedFile(z)]
    others = [z for z in names if z not in derived]
    if derived:
        ic.importDerivedFiles(parent=c.p, paths=derived)
    for fn in others:
        junk, ext = g.os_path_splitext(fn)
        if ext.startswith('.'):
            ext = ext[1:]
        if ext == 'csv':
            ic.importMindMap([fn])
        elif ext in ('cw', 'cweb'):
            ic.importWebCommand([fn], "cweb")
        # Not useful. Use @auto x.json instead.
        # elif ext == 'json':
            # ic.importJSON([fn])
        elif fn.endswith('mm.html'):
            ic.importFreeMind([fn])
        elif ext in ('nw', 'noweb'):
            ic.importWebCommand([fn], "noweb")
        elif ext == 'txt':
            ic.importFlattenedOutline([fn])
        else:
            # Make *sure* that parent.b is empty.
            last = c.lastTopLevel()
            parent = last.insertAfter()
            parent.v.h = 'Imported Files'
            ic.importFilesCommand(
                files=[fn],
                parent=parent,
                treeType='@auto', # was '@clean'
                    # Experimental: attempt to use permissive section ref logic.
            )
    c.raise_error_dialogs(kind='read')
Beispiel #16
0
def openWithTempFilePath(self, v, ext):
    """Return the path to the temp file corresponding to v and ext.
       Replaces the Commands method."""

    #TL: Added support creating temporary directory structure based on node's
    #    hierarchy in Leo's outline.
    c = self
    if c.config.getBool('open_with_clean_filenames'):
        atFileFound = False  #Track when first ancestor @file found
        #Build list of all of node's parents
        ancestor = []
        p = c.p
        while p:
            hs = p.isAnyAtFileNode()  #Get file name if we're at a @file node
            if not hs:
                hs = p.h  #Otherwise, use the entire header
            else:
                #@verbatim
                #@file type node
                if c.config.getBool('open_with_uses_derived_file_extensions'):
                    #Leo configured to use node's derived file's extension
                    if (atFileFound == False):
                        atFileFound = True  #no need to look any more.
                        #Found first ancestor @file node in outline
                        atFileBase, atFileExt = g.os_path_splitext(hs)
                        if (p == c.p):
                            #node to edit is an @file, Move ext from hs to ext
                            hs = atFileBase
                        if atFileExt:  #It has an extension
                            ext = atFileExt  #use it

            #Remove unsupported directory & file name characters
            #if(os.name == "dos" or os.name == "nt"):
            if 1:
                hsClean = ""
                for ch in hs:
                    if ch in g.string.whitespace:  #Convert tabs to spaces
                        hsClean += ' '
                    elif ch in ('\\', '/', ':', '|', '<', '>', '*',
                                '"'):  #Not allowed in Dos/Windows
                        hsClean += '_'
                    elif ch in ('"'):  #Leo code can't handle the "
                        hsClean += '\''  #replace with '
                    else:
                        hsClean += ch
                #Windows directory and file names can't end with a period
                if hsClean.endswith('.'):
                    hsClean += '_'
            else:
                hsClean = g.sanitize_filename(hs)
            #Add node's headstring (filtered) to the list of ancestors
            ancestor.append(hsClean)
            p = p.parent()

        #Put temporary directory structure under <tempdir>\Leo<uniqueId> directory
        ancestor.append("Leo" + str(id(v)))

        #Build temporary directory
        td = os.path.abspath(tempfile.gettempdir())
        #Loop through all of node's ancestors
        while len(ancestor) > 1:
            #Add each ancestor of node from nearest to farthest
            td = os.path.join(td, ancestor.pop())  #Add next subdirectory
            if not os.path.exists(td):
                os.mkdir(td)
        #Add filename with extension to the path (last entry in ancestor list)
        name = ancestor.pop() + ext
    else:
        #Use old method for unsupported operating systems
        try:
            leoTempDir = getpass.getuser() + "_" + "Leo"
        except:
            leoTempDir = "LeoTemp"
            g.es("Could not retrieve your user name.")
            g.es("Temporary files will be stored in: %s" % leoTempDir)
        td = os.path.join(os.path.abspath(tempfile.gettempdir()), leoTempDir)
        if not os.path.exists(td):
            os.mkdir(td)
        name = g.sanitize_filename(v.h) + '_' + str(id(v)) + ext

    path = os.path.join(td, name)

    return path
Beispiel #17
0
 def compare_directories(self, path1, path2):
     # Ignore everything except the directory name.
     dir1 = g.os_path_dirname(path1)
     dir2 = g.os_path_dirname(path2)
     dir1 = g.os_path_normpath(dir1)
     dir2 = g.os_path_normpath(dir2)
     if dir1 == dir2:
         return self.show("Please pick distinct directories.")
     try:
         list1 = os.listdir(dir1)
     except Exception:
         return self.show("invalid directory:" + dir1)
     try:
         list2 = os.listdir(dir2)
     except Exception:
         return self.show("invalid directory:" + dir2)
     if self.outputFileName:
         self.openOutputFile()
     ok = self.outputFileName == None or self.outputFile
     if not ok: return None
     # Create files and files2, the lists of files to be compared.
     files1 = []
     files2 = []
     for f in list1:
         junk, ext = g.os_path_splitext(f)
         if self.limitToExtension:
             if ext == self.limitToExtension:
                 files1.append(f)
         else:
             files1.append(f)
     for f in list2:
         junk, ext = g.os_path_splitext(f)
         if self.limitToExtension:
             if ext == self.limitToExtension:
                 files2.append(f)
         else:
             files2.append(f)
     # Compare the files and set the yes, no and missing lists.
     yes = []
     no = []
     missing1 = []
     missing2 = []
     for f1 in files1:
         head, f2 = g.os_path_split(f1)
         if f2 in files2:
             try:
                 name1 = g.os_path_join(dir1, f1)
                 name2 = g.os_path_join(dir2, f2)
                 val = filecmp.cmp(name1, name2, 0)
                 if val: yes.append(f1)
                 else: no.append(f1)
             except Exception:
                 self.show("exception in filecmp.cmp")
                 g.es_exception()
                 missing1.append(f1)
         else:
             missing1.append(f1)
     for f2 in files2:
         head, f1 = g.os_path_split(f2)
         if f1 not in files1:
             missing2.append(f1)
     # Print the results.
     for kind, files in (
         ("----- matches --------", yes),
         ("----- mismatches -----", no),
         ("----- not found 1 ------", missing1),
         ("----- not found 2 ------", missing2),
     ):
         self.show(kind)
         for f in files:
             self.show(f)
     if self.outputFile:
         self.outputFile.close()
         self.outputFile = None
     return None  # To keep pychecker happy.
Beispiel #18
0
def openWithTempFilePath (self,v,ext):

    """Return the path to the temp file corresponding to v and ext.
       Replaces the Commands method."""

    #TL: Added support creating temporary directory structure based on node's
    #    hierarchy in Leo's outline.
    c = self
    if c.config.getBool('open_with_clean_filenames'):
        atFileFound = False   #Track when first ancestor @file found
        #Build list of all of node's parents
        ancestor = []
        p = c.p
        while p:
            hs = p.isAnyAtFileNode() #Get file name if we're at a @file node
            if not hs:
                hs = p.h  #Otherwise, use the entire header
            else:
#@verbatim
                #@file type node
                if c.config.getBool('open_with_uses_derived_file_extensions'):
                    #Leo configured to use node's derived file's extension
                    if(atFileFound == False):
                        atFileFound = True #no need to look any more.
                        #Found first ancestor @file node in outline
                        atFileBase,atFileExt = g.os_path_splitext(hs)
                        if(p == c.p):
                            #node to edit is an @file, Move ext from hs to ext
                            hs = atFileBase
                        if atFileExt: #It has an extension
                            ext = atFileExt #use it

            #Remove unsupported directory & file name characters
            #if(os.name == "dos" or os.name == "nt"):
            if 1:
                hsClean = ""
                for ch in hs:
                    if ch in g.string.whitespace: #Convert tabs to spaces
                        hsClean += ' '
                    elif ch in ('\\','/',':','|','<','>','*', '"'): #Not allowed in Dos/Windows
                        hsClean += '_'
                    elif ch in ('"'): #Leo code can't handle the "
                        hsClean += '\''   #replace with '
                    else:
                        hsClean += ch
                #Windows directory and file names can't end with a period
                if hsClean.endswith( '.' ):
                    hsClean += '_'
            else:
                hsClean = g.sanitize_filename(hs)
            #Add node's headstring (filtered) to the list of ancestors
            ancestor.append(hsClean)
            p = p.parent()

        #Put temporary directory structure under <tempdir>\Leo<uniqueId> directory
        ancestor.append( "Leo" + str(id(v)))

        #Build temporary directory
        td = os.path.abspath(tempfile.gettempdir())
        #Loop through all of node's ancestors
        while len(ancestor) > 1:
            #Add each ancestor of node from nearest to farthest
            td = os.path.join(td, ancestor.pop()) #Add next subdirectory
            if not os.path.exists(td):
                os.mkdir(td)
        #Add filename with extension to the path (last entry in ancestor list)
        name = ancestor.pop() + ext
    else:
        #Use old method for unsupported operating systems
        try:
            leoTempDir = getpass.getuser() + "_" + "Leo"
        except:
            leoTempDir = "LeoTemp"
            g.es("Could not retrieve your user name.")
            g.es("Temporary files will be stored in: %s" % leoTempDir)
        td = os.path.join(os.path.abspath(tempfile.gettempdir()), leoTempDir)
        if not os.path.exists(td):
            os.mkdir(td)
        name = g.sanitize_filename(v.h) + '_' + str(id(v)) + ext

    path = os.path.join(td,name)

    return path