TOML and TextProperties

This thread is spun out of the thread in which I asked for a recommendation for a TOML parser, as it seemed sufficiently separate from that request.

In short, TextProperties-tags appear to work nicely!

… As long as they weren’t derived from a TOML-parsing. In that case, they don’t seem to work at all!

Specifically, it seems that TOML doesn’t like the escape sequences used by TextProperties: “\1” and “\2”–or at least, I haven’t yet found a way to successfully include them. And if the backslashes of those escape sequences are themselves escaped, they end up as just the text “\1” and “\2”, which TextProperties doesn’t recognise.

See the following test-program, which demonstrates the issue on my machine:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import TextProperties, TextPropertiesManager
from direct.gui.OnscreenText import OnscreenText

import tomli

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        textPropertySlanted = TextProperties()
        textPropertySlanted.setSlant(0.3)

        textPropManager = TextPropertiesManager.getGlobalPtr()
        textPropManager.setProperties("italic", textPropertySlanted)

        self.label = OnscreenText(text = "Non-italic",
                                  pos = (0, 0),
                                  scale = 0.2)

        self.accept("1", self.testBasicString)
        self.accept("2", self.testTomlString)

    def testBasicString(self):
        self.label.setText("\1italic\1Italics!\2")

    def testTomlString(self):
        tomlString = "cat = '''\\1italic\\1TOML Italics!\\2'''"
        #tomlString = "cat = '''\1italic\1TOML Italics!\2'''" # <-- Breaks
        result = tomli.loads(tomlString)
        self.label.setText(result["cat"])

game = Game()
game.run()

In short, it sets up an OnscreenText with some basic text, as well as a TextProperties that produces an italic effect.

Then:

  • When the user presses “1”, it sets the text to be a simple string that contains the relevant TextProperties markup.
  • When the user presses “2”, it sets the text to be a string derived from TOML, and that likewise contains the relevant markup–at least in its raw form.

On my end, at least, the former works, and the latter doesn’t.

Does anyone see a way around this?

And is it worth considering a different set of tags for TextProperties. After all, even if the conflict with TOML is resolved, the use of backslashes as escape-characters may result in another, similar clash with some other module in the future…

The correct TOML syntax is not \1, but \u0001. However, tomli doesn’t accept that. Perhaps this is a bug in tomli, but I’d need to check the TOML spec to be sure.

Alternatively, you could just use \\1 and call .decode('string_escape') on the string in Python. Or use a different tag, like $1 that you use a replace operation on.

Ah, I think that I forgot to mention that I did indeed try that, too. As you say, it doesn’t work.

Hmm, perhaps–but that does mean more work being done in the background on strings, and thus being done potentially fairly often.

I will consider it, however, I intend.

However, I do still think that a change–or at least an alternative–to the tags used by TextProperties is worth thinking about. It seems preferable to me to have tags that are unlikely to be seen as escape sequences–valid or otherwise–by parsers like TOML, whether current or future.

Actually, I made a mistake when trying it, since I need to double-escape when entering a TOML string in Python. I’ll use a raw string instead. You’ll see that this works:

import tomli
tomli.loads(r'blah = "\u0001"')

So, I see no problems with going ahead and using \u0001 et al.

I’m happy to consider changing the TextProperties tags, though. Feel free to open a discussion on GitHub to suggest some.

Note that TOML distinguishes between regular strings (with double-quotes) and literal strings (with single-quotes). In your example, you used single quotes, which makes it a literal string (similar to the r prefix in Python), and that is why the escape sequences were not parsed.

Ah, so indeed it does! Thank you so much! :slight_smile:

I recall that I’ve tried both, and even tried the “uXXXX” nomenclature–but I presumably missed the one precise combination of factors that made it work!

I might well do that tomorrow–thank you! :slight_smile:

All right, it wasn’t “tomorrow”, as it turned out, but I did make an issue to suggest new tags! :slight_smile: