Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Clarification: syntax for file name description

in General Posts: 58

I just want to clarify the new way to write file names with Codea 3.x.

The file name used to be just a string such as
tt=readText("Dropbox:file1")

But since Codea 3.x introduced assets key stile, the code should be
tt= readText( asset.documents.Dropbox .. "file1.txt")
blanks are required before and after ".." in order to connect asset location description and file name with file type extension.

file name can be a variable
fileName="file1.txt"
tt=readText(asset.documents.Dropbox .. fileName)

However, when choosing the file directly from code editor, it can be written as
tt= readText( asset.documents.Dropbox._file1)
no blanks nor file type are required but an underscore.

Are there any other points to be noted in syntax for file name description?

Tagged:

Comments

  • dave1707dave1707 Mod
    Posts: 8,398

    @Makoto It depends if the file exists or not. Blanks aren’t required before the ..
    If the file exists, then you can just tap between the () and select it. If the file doesn’t exist or it has special characters in the name, then you might need “” or [] or .. with the name. It also depends if you specify the extension name with the file name. Normally if the file exists, I just select it in between the (). If the file doesn’t exist yet, then I just try different things around the name until I don’t get a warning. I don’t know if there’s specific rules for what to do for each situation. It kind of varies because sometimes it works multiple ways.

        f=readText(asset.documents.Dropbox["bkA200505-1640.txt"])
        f=readText(asset.documents.Dropbox"bkA200505-1640.txt")
        f=readText(asset.documents.Dropbox.test3)
        f=readText(asset.documents.Dropbox..qwert)
    
        saveText(asset.documents.Dropbox.."qwert-123.txt")
        saveText(asset.documents.Dropbox.test3)
        saveText(asset.documents.Dropbox..qwert)
    
        f=readImage(asset.documents.Dropbox.test2_png)
        f=readImage(asset.documents.Dropbox..test22_png)
    
        saveImage(asset.documents.Dropbox.sky)
        saveImage(asset.documents.Dropbox..qwert)
    
        sprite(asset.documents.Dropbox.sky)
        sprite(asset.documents.Dropbox..sky45.png)
    
  • SimeonSimeon Admin Mod
    edited May 12 Posts: 5,364

    @Makoto an underscore shouldn't be necessary unless the file begins with a character that can't be used in Lua (like a space, number, or symbol)

    You should be able to write

    readText( asset.documents.file1 )

    If a file called file1.txt exists in your documents folder

    If the file doesn't exist (say you want to create it, using saveText), you can specify the path as follows:

    saveText( asset.documents .. "file1.txt", "Hello World" )

    More notes on underscores:

    Because you can't use certain symbols in variable names in Lua (they can't start with a number, they can't contain a space, they can't contain quotes, etc.) you will see them replaced with underscores when you select them via autocomplete or through the picker

    For example, a file called "A Hero's Quest:Tavern Music" would be represented as asset.builtin.A_Hero_s_Quest.Tavern_Music (because Lua doesn't let you put space (), or quote (') in variable names.

    You could also access this file with the raw strings by doing:

    asset.builtin["A Hero's Quest"]["Tavern Music"]

  • Posts: 616

    Is there a useful way to find out if the file exists in code?

  • dave1707dave1707 Mod
    edited May 12 Posts: 8,398

    @RonJeffries I think I mentioned something similar already. It used to be if you tried to read a file that didn’t exist, it returned nil and you could code for that. Now, if you try to read a file that doesn’t exist, the code exits with an error. I haven’t checked recently if that was corrected or not.

    PS. Just tried it and the code exits with an error.

  • SimeonSimeon Admin Mod
    Posts: 5,364

    @RonJeffries there isn't a good way to do it, but that's a great question. I will add an exists property to the asset key system so you can check whether an asset exists in the file system

  • SimeonSimeon Admin Mod
    Posts: 5,364

    @dave1707 I'm getting nil when reading a text file that doesn't exist

    local blah = readText( asset.documents .. "MadeUpFile.txt" )
    print(blah)
    
  • dave1707dave1707 Mod
    Posts: 8,398

    @Simeon I guess it just depends on the syntax. I didn’t have the “ “ around my file name. It didn’t give me an error in the editor, so I thought it was OK. It just gave an error message when I tried to run the code. I’ll just have to remember to put “ “ around the name.

  • dave1707dave1707 Mod
    Posts: 8,398

    @Simeon Here's what I mean about the syntax. It’s like you need to try different things. Some times you need a single period, other times you need a double period , or double quotes or double brackets. I thought maybe if you didn’t get an editor error message, then it should work. So from what you said, everything should work OK. You just need to try different combinations until it does.

    function setup()
        str1=readText(asset.documents.Dropbox.test3)        -- file exist, reads OK
        str2=readText(asset.documents.Dropbox.."test3")     -- file exists, returns nil
        str3=readText(asset.documents.Dropbox.."test31")    -- file doesn't exist, returns nil
        print("str1 ",str1)
        print("str2 ",str2)
        print("str3 ",str3)
    end
    
  • SimeonSimeon Admin Mod
    Posts: 5,364

    @dave1707 when you use quotes " you must use the full filename, including the extension.

    function setup()
        str1=readText(asset.documents.Dropbox.test3)        -- file exist, reads OK
        str2=readText(asset.documents.Dropbox.."test3.txt")     -- (assuming the file has a .txt extension)
        str3=readText(asset.documents.Dropbox.."test31")    -- file doesn't exist, returns nil
        print("str1 ",str1)
        print("str2 ",str2)
        print("str3 ",str3)
    end
    

    When you get the autocompleted identifiers for files the file extensions are not included — unless two or more files with the same name (but different extensions) live in the same folder. So if you had "test3.txt" and "test3.png" in your Dropbox you would get

    asset.documents.Dropbox.test3_txt and
    asset.documents.Dropbox.test3_png

    Whereas if you only have "test3.txt" in the folder you'd get an autocomplete identifier like:

    asset.documents.Dropbox.test3

    If you want to use the actual file name you can do that with the bracket syntax:

    asset.documents.Dropbox["test3.txt"]

  • dave1707dave1707 Mod
    Posts: 8,398

    @Simeon I thought I fully understood the asset syntax, but I guess I didn’t. Thanks for the added info.

  • SimeonSimeon Admin Mod
    edited May 12 Posts: 5,364

    @RonJeffries here's a little app that lets you check if a file exists

    -- File Exists
    function setup()
        print("Checking asset.builtin.Effects")
    
        local folder = asset.builtin.Effects        
    
        parameter.text("FileName", "Ripple.shader", function ()        
            exists = doesExist(FileName, folder)        
        end)
    
        parameter.action("List Folder", function ()
            for _,v in pairs(folder.all) do
                print(v.name)
            end
        end)
    
        exists = doesExist(FileName, folder)
    end
    
    function doesExist(name, folder) 
        return folder[name] ~= nil
    end
    
    
    function draw()
        background(40, 40, 50)
    
        strokeWidth(5)
    
        fill(255)
        textMode(CENTER)
        if exists then
            text("File Exists", WIDTH/2, HEIGHT/2)
        else 
            text("File Does Not Exist", WIDTH/2, HEIGHT/2)
        end
    end
    

    Basically you check if folder[fileName] ~= nil. If you get an asset key, then the file exists. If you get nil, it doesn't.

    So if asset.documents["MySprite.png"] is nil, then it's not there.

    Side note: this is different to asset.documents .. "MySprite.png". The concatenation (..) operator will create an asset key for you by appending a given file name to a folder name, this allows you to specify asset keys for files which don't exist (so you can create them)

  • edited May 12 Posts: 616

    thanks!

    in the .. examples simeon and dave show above, i'd have expected to have to say ..".text3", not just .."text3", etc.

  • SimeonSimeon Admin Mod
    edited May 13 Posts: 5,364

    @RonJeffries .. is the concatenation operator, and in this case it is used to construct a new path given an existing folder and a file/folder name

    So it might make more sense to expect folder .. "/text3.txt". As you are appending onto a path, though in this API we omit the path separator (/) because where and how to place path separators when concatenating path elements should be handled by the system

    I'll be writing a more interesting file and asset example soon

  • Posts: 616

    my thought is that "asset.documents" .. "test.txt" is "asset.documentstest.txt" not "asset.documents.test.txt" but I suppose it's just an overload of ".." with smarts.

  • Posts: 616

    ok, so

    saveImage(asset.documents.Dropbox.."unitpic.png", img)

    saves, you guessed it, to On My iPad > Codea > Dropbox.assets

    Is that related to Dropbox at all? How do I specify an arbitrary location in Files, and where is this documented, please?

  • SimeonSimeon Admin Mod
    Posts: 5,364

    @RonJeffries yeah asset.documents represents the path to the folder "Documents/"

    asset.documents.Dropbox represents "Documents/Dropbox.assets/"

    At the moment you cannot specify an arbitrary location in Files. But this is why I introduced asset keys, it implements the architecture I need to get there

    iOS restricts access to files, so Codea cannot read or write any files on your system outside of its own Documents folder. The only way Codea can access another folder is if we present the system file picker and you explicitly select a folder or file. Codea will be granted access to only that folder or file and can store a bookmark to it

    This is what I'm planning to introduce with asset keys — something like you type asset. and in the autocomplete bar there is a button for "External Folder", and tapping that brings up the file picker UI, selecting the folder then creates a bookmark for Codea and allows you to reference the folder in your code

  • Posts: 616

    it's weird. i'm sure you'll get there. thanks!

  • Posts: 58

    I wish to have a sub-folder capability within Dropbox, taking advantage of the asset keys system.
    I mean something like;
    textRead(asset.documents.Dropbox.folder1["test3.txt"])
    Then I can save a set of data relating to one project in one folder together. It will make easier not only to manage numerous files for number of projects but also to implement auto linkage of required files in exporting a zipped project file to Xcode.
    Currently, it seems Codea detects the files in the folder "Dropbox/アプリ/Codea" only and classify them by their file types, e.g. text, image, sound, etc. However, it ignores subfolders under Codea folder.
    Codea project editor deems ".folder1" following Dropbox as an asset and give me an error message "Asset 'folder1' does not exist", even there is a subfolder "filder1" in the Codea folder.

Sign In or Register to comment.